/********************************************************************** * * * **********************************************/ /* c8 ignore next 2 */ ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) (function(require){ var module={} // make module AMD/node compatible... /*********************************************************************/ var object = require('ig-object') /*********************************************************************/ var SetProtoMixin = module.SetProtoMixin = object.Mixin('SetMixin', 'soft', { iter: function*(){ for(var e of this){ yield e } }, // Set set operation shorthands... unite: function(other=[]){ return new Set([...this, ...other]) }, intersect: function(other){ var test = other.has ? 'has' : 'includes' return new Set([...this] .filter(function(e){ return other[test](e) })) }, subtract: function(other=[]){ other = new Set(other) return new Set([...this] .filter(function(e){ return !other.has(e) })) }, sort: function(values=[]){ values = (typeof(values) == 'function' || values === undefined) ? [...this].sort(values) : values var del = this.delete.bind(this) var add = this.add.bind(this) new Set([...values, ...this]) .forEach(function(e){ if(this.has(e)){ del(e) add(e) } }.bind(this)) return this }, replace: function(old, value, ordered=true){ // nothing to do... if(!this.has(old) || old === value){ return this } if(ordered){ var order = [...this] // XXX is this fast enough??? order[order.lastIndexOf(old)] = value } // replace... this.delete(old) this.add(value) ordered && this.sort(order) return this }, // NOTE: if index is <0 then the value is prepended to the set, if // it's >=this.size then the value will be appended. // if ordered is set to false in both cases the value is appended. // XXX should this be implemented via .splice(..) ??? replaceAt: function(index, value, ordered=true){ // append... if(index >= this.size){ this.add(value) return this } // prepend... if(index < 0){ index = 0 var order = [, ...this] // replace... } else { var order = [...this] var old = order[index] // nothing to do... if(old === value){ return this } } ordered && (order[index] = value) // replace... this.has(old) && this.delete(old) this.add(value) ordered && this.sort(order) return this }, // XXX do we need this??? // ...should this be enough??? // new Set([...set].splice(..)) splice: function(from, count, ...items){ var that = this var order = [...this] var removed = order.splice(...arguments) // update the set... removed.forEach(this.delete.bind(this)) items.forEach(this.add.bind(this)) this.sort(order) return removed }, }) SetProtoMixin(Set.prototype) /********************************************************************** * vim:set ts=4 sw=4 : */ return module })