Last active
December 13, 2015 20:28
-
-
Save teramako/4970442 to your computer and use it in GitHub Desktop.
Uniqな配列的オブジェクト。 Setオブジェクトを使ってる。Arrayの操作に加えて、UniqArray#has による存在真偽は Array#indexOf よりかなり高速なはず(参照: http://jsperf.com/array-indexof-vs-set-has )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @class UniqArray {{{1 | |
* @constructor | |
* @extends Array | |
*/ | |
function UniqArray(list = []) { | |
Object.defineProperty(this, "__set__", { value: new Set(list) }); | |
list = [...this.__set__]; | |
var len = list.length; | |
for (let i = 0; i < len; ++i) { | |
this[i] = list[i]; | |
} | |
Object.defineProperty(this, "length", { writable: true, value: len }); | |
} | |
// UniqArray.prototype {{{2 | |
(function() { | |
var ap = Array.prototype; | |
UniqArray.prototype = mixin(Object.create(ap), /** @lends Items.prototype */ { | |
constructor: UniqArray, | |
has: function UA_has (item) { | |
return this.__set__.has(item); | |
}, | |
delete: function UA_delete (item) { | |
if (this.__set__.delete(item)) { | |
ap.splice.call(this, ap.indexOf.call(this, item), 1); | |
return true; | |
} | |
return false; | |
}, | |
push: function UA_push (item) { | |
if (this.has(item)) | |
return false; | |
this.__set__.add(item); | |
ap.push.call(this, item); | |
return true; | |
}, | |
unshift: function UA_unshift (item) { | |
if (this.has(item)) | |
return false; | |
this.__set__.add(item); | |
ap.unshift.call(this, item); | |
return true; | |
}, | |
pop: function UA_pop () { | |
var item = ap.pop.call(this); | |
this.__set__.delete(item); | |
return item; | |
}, | |
shift: function UA_shift () { | |
var item = ap.shift.call(this); | |
this.__set__.delete(item); | |
return item; | |
}, | |
splice: function UA_splice (index, count, ...list) { | |
var delList = ap.splice.call(this, index, count); | |
for (let delItem of delList) { | |
this.__set__.delete(delItem); | |
} | |
for (let item of list) { | |
if (this.__set__.has(item)) | |
continue; | |
this.__set__.add(item); | |
ap.splice.call(this, index++, 0, item); | |
} | |
return delList; | |
}, | |
slice: function UA_slice (index, count) { | |
return new UniqArray(ap.slice.call(index, count)); | |
}, | |
concat: function UA_concat (...list) { | |
return new UniqArray(ap.concat.apply(this, list)); | |
}, | |
}); | |
}()); // 2}}} | |
// 1}}} | |
function mixin (aTarget, aSource) { | |
for (var key of Object.getOwnPropertyNames(aSource)) { | |
let desc = Object.getOwnPropertyDescriptor(aSource, key); | |
desc.enumerable = false; | |
Object.defineProperty(aTarget, key, desc); | |
} | |
return aTarget; | |
} |
GoogleChromeにも Set があるけど、new Set([...])
のコンストラクトとか、rest parameter がないので、まだ使えないと思う。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
delete 演算子で delete uniqArray[0] とかやると整合性が取れなくなるので、禁止。この整合性を取るとなると Proxy が必要になりそう。