Skip to content

Instantly share code, notes, and snippets.

@teramako
Last active December 13, 2015 20:28
Show Gist options
  • Save teramako/4970442 to your computer and use it in GitHub Desktop.
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 )
/**
* @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;
}
@teramako
Copy link
Author

delete 演算子で delete uniqArray[0] とかやると整合性が取れなくなるので、禁止。この整合性を取るとなると Proxy が必要になりそう。

@teramako
Copy link
Author

GoogleChromeにも Set があるけど、new Set([...]) のコンストラクトとか、rest parameter がないので、まだ使えないと思う。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment