UNPKG

@garyp/common-object-x

Version:
621 lines (493 loc) 13 kB
const { CommonObjectx } = require('./CommonObjectx'); //--------------------------------------------------------------------- //--------------------------------------------------------------------- "use strict"; class Collectionx extends CommonObjectx { constructor() { super(); } /* -- static methods -- fromRaw fromNumsString withWith fromFormattedNumsString intervalFromTo fromCompositeNumsString fromCompositeFormattedNumsString numsSetFrom withWithWithWith withWithWith with coerce fromRepeat fromFreeForm fromFreeFormNums */ add(elem) { //Manual this.raw().push(elem); } addBeforeIndex(elem, index) { const jsIndex = this.tools().privateIndexForPublic(index); //splice (2, 0, 19) is just like --> coll add: 19 beforeIndex: 2 //splice in "elem" at jsIndex (deletions = 0) this.coll().splice(jsIndex, 0, elem); } addAll(coll) { //Manual var raw = coll.zzunwrap(); for (var ea of raw) this.add(ea); } addExt(elemOrColl) { if(this.tools().isCollection(elemOrColl)) this.addAll(elemOrColl) else this.add(elemOrColl); } asCsv() { //delimited with csv return this.asDelimitedBracket(",",'"'); } asDelimited(delimiter) { return this.asDelimitedBracket(delimiter,null); } asDelimitedBracket(delimiter, bracket) { var collObjects, strDelimiter, strm, sz, delimTrimmed; collObjects = this.coll(); strDelimiter = delimiter.toString(); strm = this.newStream(); sz = collObjects.size(); delimTrimmed = delimiter.zzwrap().trim(); var _unwrappedcoll_ = collObjects.zzunwrap(); for (var ii=0; ii<_unwrappedcoll_.length; ii++) { var ea = _unwrappedcoll_[ii]; var index = this.tools().publicIndexForPrivate(ii); {var value; value = ea.asString(); if((bracket != null) && value.zzwrap().includes(delimTrimmed)) value = value.zzwrap().asBracketedWith(bracket); strm.nextPutAll(value); if(index < sz) strm.show(strDelimiter);} } return strm.contents(); } asHstring() { return this.raw().map(ea => ea.toString()).join(" "); } asVstring() { return this.raw().map(ea => ea.toString()).join("\n"); } at(index) { //Manual return this.raw()[this.tools().privateIndexForPublic(index)]; } atIfAbsent(smalltalkIndex, block) { return this.checkIndex(smalltalkIndex) ? this.at(smalltalkIndex) : block(); } basicAsDeflated() { return (self.zzunwrap().map(each => each.zzwrap().asDeflatedObject())).zzwrap(); } checkIndex(index) { if(this.isEmpty()) return false; return (index >= 1) && index <= this.size(); } coll() { //foo return this.raw(); } collect(fct) { //Manual return this.raw().map(elem => fct.evaluateFor(elem)); } copyO() { var copy; copy = this.newColl(); this.zzunwrap().forEach(ea => { copy.add(ea.copyO()) }); return copy; } doWithIndex(fct) { var coll = this.raw(); for (var index in coll) fct(coll[index], index); } equalsEff(other) { if(!(this.objectEquals(this.size(),other.size()))) return false; for (var i=1; i<=this.size(); i++) if(!(this.at(i).zzwrap().equalsEff(other.at(i).zzwrap()))) return false; return true; } find(block) { //compatibility with js return this.findFor(block); } findFor(block) { var index; index = this.indexFor(block); return index > 0 ? this.at(index) : null; } first() { return this.at(1); } firstL() { return this.first(); } includes(item) { return this.raw().includes(item); } includesFor(block) { return this.findFor(block) != null; } indexFor(fct) { //Manual return this.tools().publicIndexForPrivate(this.coll().findIndex(fct)); } indexOf(elem) { //Answer public (smalltalk) index. Thx fyt if(!(this.tools().isKindOf(elem,this.constructor))) return this.indexOfPrim(elem); var _unwrappedcoll_ = this.zzunwrap(); for (var ii=0; ii<_unwrappedcoll_.length; ii++) { var each = _unwrappedcoll_[ii]; var index = this.tools().publicIndexForPrivate(ii); if(this.objectEquals(elem,each)) return index } return 0; } indexOfKey(key) { //Answer public (smalltalk) index. Thx fyt var _unwrappedcoll_ = this.zzunwrap(); for (var ii=0; ii<_unwrappedcoll_.length; ii++) { var each = _unwrappedcoll_[ii]; var index = this.tools().publicIndexForPrivate(ii); if(this.objectEquals(each.firstL(),key)) return index } return 0; } indexOfObject(elem) { //equals by identity return this.indexFor(each => each === elem); } indexOfPrim(elem) { //Manual return this.tools().publicIndexForPrivate(this.raw().indexOf(elem)); } initialize() { super.initialize(); this.raw(this.newRawColl()); } isCollection() { return true; } isCollectionable() { //Can we act as a collection? return true; } isEmpty() { return this.objectEquals(this.size(),0); } isPairable() { return this.objectEquals(this.size(),2); } join(delimiter) { //Note: #join is supported in both st and js return this.raw().join(delimiter); } last() { return this.at(this.size()); } lastL() { return this.last(); } min() { var min; if(this.isEmpty()) this.throw("Cannot find min of empty collection"); min = this.first(); if(this.objectEquals(this.size(),1)) return min; this.zzunwrap().forEach(ea => { if(ea < min) min = ea }); return min; } notEmpty() { return !this.isEmpty(); } pairsAsDictionary() { var temp1; temp1 = this.newDict(); temp1.addAll(this); return temp1; } reduceWith(binaryFct, initialValue) { //Manual return this.raw().reduce(binaryFct, initialValue); } reject(selectFct) { return this.select((each) => !selectFct(each)); } remove(elem) { var index; index = this.indexOf(elem); if(index > 0) this.removeIndex(index); } removeAll() { this.raw(this.newRawColl()); } removeIndex(index) { //Manual var jsindex = this.tools().privateIndexForPublic(index); //splice() - first param is 0-based index to start remove, 2nd is # of elems to remove //With "splice" elements are adderd/removed in-place this.raw().splice(jsindex, 1); } removeKey(key) { var index; index = this.indexOfKey(key); if(index >= 1) this.removeIndex(index); } removeObject(elem) { //By identity var index; index = this.indexFor(ea => ea === elem); if(index >= 1) this.removeIndex(index); } second() { return this.at(2); } secondL() { return this.second(); } select(selectFct) { return zzwrap(this.coll().zzunwrap().filter(each => selectFct(each))); } size() { //Manual return this.raw().length; } sliceFrom(start) { //Note: 'sliceFrom()' is manual extension on String return this.raw().sliceFrom(this.tools().privateIndexForPublic(start)); } sliceFromTo(start, stop) { //start inclusive stop exclusive //Note: 'sliceFromTo()' is manual extension on String return this.raw().sliceFromTo(this.tools().privateIndexForPublic(start),this.tools().privateIndexForPublic(stop)); } sliceTo(start) { //Note: 'sliceTo()' is manual extension on String return this.raw().sliceTo(this.tools().privateIndexForPublic(start)); } sumWith(valueGetter) { return this.reduceWith((sum, ea) => sum + valueGetter(ea),0); } valueAtKey(key) { //Assume elements are key-value pairs var index; index = this.indexOfKey(key); return index >= 1 ? this.at(index).secondL() : null; } //Class Methods static coerce(arg) { if(arg.isCommonObjectx() && arg.isCollectionable()) return arg; return this.tools().isCollection(arg) ? this.on(arg) : this.with(arg); } static fromNumsString(aString) { /* Free Form Result 1 #(1) 5-7 #(5, 6, 7) */ var s, dash, coll, strm, left, right; s = aString.zzwrap(); dash = "-"; coll = this.newColl(); if(!(s.includes(dash))) {coll.add(this.tools().coerceNumber(s)); return coll;} strm = this.newStream(s); left = this.tools().coerceNumber(strm.upTo(dash)); right = this.tools().coerceNumber(strm.rem()); for (var i=left; i<=right; i++) coll.add(i); return coll; } static fromRaw(coll) { var temp1; temp1 = new this(); temp1.addAll(coll); return temp1; } static intervalFromTo(start,stop) { var coll; coll = this.newColl(); for (var i=start; i<=stop; i++) coll.add(i); return coll; } static fromRepeat(value,count) { var coll; coll = this.newObject(); var timesRepeatCounter = 1; while (timesRepeatCounter <= count) {coll.add(value) timesRepeatCounter = timesRepeatCounter + 1;} return coll; } static fromFreeForm(s) { /* Free Form Result 1 #(1) 2, 5-7, 8 #(2, 5, 6, 7, 8) 2-3, 5 #(2, 3, 5) 5, 6, 7, 8 #(5, 6, 7, 8) */ var subStrings, coll; subStrings = this.newStream(s).parseAllDelimitedBy(","); coll = new this(); subStrings.zzunwrap().forEach(sub => { coll.add(sub) }); return coll; } static fromFreeFormNums(s) { /* Free Form Result 1 #(1) 2, 5-7, 8 #(2, 5, 6, 7, 8) 2-3, 5 #(2, 3, 5) 5, 6, 7, 8 #(5, 6, 7, 8) */ var subStrings, coll; subStrings = this.newStream(s).parseAllDelimitedBy(","); coll = new this(); subStrings.zzunwrap().forEach(sub => { coll.addAll(this.fromFormattedNumsString(sub)) }); return coll; } static withWith(a,b) { var temp1; temp1 = new this(); temp1.add(a); temp1.add(b); return temp1; } static fromFormattedNumsString(aString) { /* Free Form Result 1 #(1) 5-7 #(5, 6, 7) */ var s, dash, coll, strm, left, right; s = aString.zzwrap(); dash = "-"; coll = this.newColl(); if(!(s.includes(dash))) {coll.add(this.tools().coerceNumber(s)); return coll;} strm = this.newStream(s); left = this.tools().coerceNumber(strm.upTo(dash)); right = this.tools().coerceNumber(strm.rem()); for (var i=left; i<=right; i++) coll.add(i); return coll; } static withWithWithWith(a,b,c,d) { var temp1; temp1 = new this(); temp1.add(a); temp1.add(b); temp1.add(c); temp1.add(d); return temp1; } static with(a) { var temp1; temp1 = new this(); temp1.add(a); return temp1; } static fromCompositeFormattedNumsString(s) { /* Free Form Result 1 #(1) 2, 5-7, 8 #(2, 5, 6, 7, 8) 2-3, 5 #(2, 3, 5) 5, 6, 7, 8 #(5, 6, 7, 8) */ var subStrings, coll; subStrings = this.newStream(s).parseAllDelimitedBy(","); coll = new this(); subStrings.zzunwrap().forEach(sub => { coll.addAll(this.fromFormattedNumsString(sub)) }); return coll; } static fromCompositeNumsString(s) { /* Free Form Result 1 #(1) 2, 5-7, 8 #(2, 5, 6, 7, 8) 2-3, 5 #(2, 3, 5) 5, 6, 7, 8 #(5, 6, 7, 8) */ var subStrings, coll; subStrings = this.newStream(s).parseAllDelimitedBy(","); coll = new this(); subStrings.zzunwrap().forEach(sub => { coll.addAll(this.self().fromNumsString(sub)) }); return coll; } static numsSetFrom(aString) { /* Free Form Result 1 #(1) 5-7 #(5, 6, 7) */ var s, dash, coll, strm, left, right; s = aString.zzwrap(); dash = "-"; coll = this.newColl(); if(!(s.includes(dash))) {coll.add(this.tools().coerceNumber(s)); return coll;} strm = this.newStream(s); left = this.tools().coerceNumber(strm.upTo(dash)); right = this.tools().coerceNumber(strm.rem()); for (var i=left; i<=right; i++) coll.add(i); return coll; } static withWithWith(a,b,c) { var temp1; temp1 = new this(); temp1.add(a); temp1.add(b); temp1.add(c); return temp1; } } Collectionx.prototype.includesEff = function(substring) { return this.includes(substring); } Array.prototype.sliceFromTo = function(from, to) { return this.slice(from, to); } Array.prototype.sliceFrom = function(from) { return this.slice(from); } Array.prototype.sliceTo = function(to) { return this.slice(0, to); } Array.prototype.isEmpty = function() { return this.length == 0; } Array.prototype.notEmpty = function() { return !this.isEmpty(); } Array.prototype.isPairable = function() { return this.length == 2; } Array.prototype.firstL = function() { return this[0]; } Array.prototype.secondL = function() { return this[1]; } Array.prototype.lastL = function() { return this[this.length - 1]; } exports.Collectionx = Collectionx;