mirror of
https://github.com/flynx/types.js.git
synced 2025-10-28 10:00:08 +00:00
147 lines
3.8 KiB
JavaScript
147 lines
3.8 KiB
JavaScript
/**********************************************************************
|
|
*
|
|
*
|
|
*
|
|
**********************************************/ /* 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 stoppable = require('ig-stoppable')
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
// Wrap .map(..) / .filter(..) / .reduce(..) / .. to support STOP...
|
|
//
|
|
// NOTE: internally these are implemented as for-of loops (./generator.js)
|
|
var stoppableSet = function(iter){
|
|
return function(func){
|
|
return new Set([...this][iter](...arguments)) } }
|
|
var stoppableValue = function(iter, no_return=false){
|
|
return function(func){
|
|
var res = [...this][iter](...arguments)
|
|
return no_return ?
|
|
undefined
|
|
: res } }
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
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 },
|
|
|
|
filter: stoppableSet('filter'),
|
|
map: stoppableSet('map'),
|
|
reduce: stoppableValue('reduce'),
|
|
reduceRight: stoppableValue('reduceRight'),
|
|
forEach: stoppableValue('map', true),
|
|
})
|
|
|
|
|
|
SetProtoMixin(Set.prototype)
|
|
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
* vim:set ts=4 sw=4 : */ return module })
|