JavaScript: Array.prototype.uniq

Array.prototype.uniq = function(){
    for (var i=0,l=this.length; i<l; i++) {
        if (this.indexOf(this[i]) < i) {
            this.splice(i--, l-- && 1);
        }
    }
    return this;
};
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9].uniq()
// -> [3, 1, 4, 5, 9, 2, 6, 8, 7]

アレイのuniq JavaScriptで どう書く?org

アレイのuniqどう書く?org - 口から出まかせ

もう同じアプローチの解法は出てるんだけど、lengthを変数に取っておくとちょっと効率化できる。

あと、問答無用で破壊するのがJavaScript流だと思うので、そうした。

潰したくないときは、ary.concat().uniq()のように事前に複製する。


Core JavaScript 1.5 Reference:Global Objects:Array:indexOf - MDC

Array#indexOfは普通に===演算子でチェックする。

ハッシュを使ってのfor...in構文だと要素がオブジェクトのときとか困るし、意外と悪くないアプローチに思える。

問題はArray#indexOfが1.6の新機能なのと、[1,2] === [1,2]がfalseになるあたり……

unevalでmap、uniq、evalでmapとかかなあ。

[1, "2", {a: 3}, [4, 5], 1, "2", {a: 3}, [4, 5], 6].uniq()
// -> [1, "2", Object a=3, [4, 5], Object a=3, [4, 5], 6]

[1, "2", {a: 3}, [4, 5], 1, "2", {a: 3}, [4, 5], 6].map(uneval).uniq().map(eval)
// -> [1, "2", Object a=3, [4, 5], 6]
//    非破壊

追記

Array#indexOfだと最後まで走査してしまって無駄が多いので、ちょっと効率化。

Array.prototype.uniq = function(){
    for (var i=0,l=this.length; i<l; i++) {
        for (var j=0; j<i; j++) {
            if (this[i] === this[j]) {
                this.splice(i--, l-- && 1);
            }
        }
    }
    return this;
};

Comment: 0

コメントの受け付けは終了しました。

Trackback: 0

トラックバックの受け付けは終了しました。