web-dev-qa-db-ja.com

JavaScriptで重複を含む配列から一意の値の配列を取得する方法は?

['0','1','1','2','3','3','3']配列を指定すると、結果は['0','1','2','3']になります。

107
NaveenDAlmeida

編集済み

ES6ソリューション:

[...new Set(a)];

代替案:

Array.from(new Set(a));

古い応答。 O(n ^ 2)(大きな配列では使用しないでください!)

var arrayUnique = function(a) {
    return a.reduce(function(p, c) {
        if (p.indexOf(c) < 0) p.Push(c);
        return p;
    }, []);
};
257
Pedro L.

順序を維持する場合:

arr = arr.reverse().filter(function (e, i, arr) {
    return arr.indexOf(e, i+1) === -1;
}).reverse();

組み込みの逆インデックスがないため、配列を逆にし、重複を除外してから逆に戻します。

フィルター関数は、現在のインデックスの後(元の配列の前)の要素の出現を探します。見つかった場合、この要素をスローします。

編集:

または、lastindexOfを使用できます(順序を気にしない場合)。

arr = arr.filter(function (e, i, arr) {
    return arr.lastIndexOf(e) === i;
});

これにより、一意の要素が保持されますが、最後の出現のみが保持されます。これは、['0'、 '1'、 '0']が['0'、 '1']ではなく['1'、 '0']になることを意味します。

50
beatgammit

配列プロトタイプ関数は次のとおりです。

Array.prototype.unique = function() {
    var unique = [];
    for (var i = 0; i < this.length; i++) {
        if (unique.indexOf(this[i]) == -1) {
            unique.Push(this[i]);
        }
    }
    return unique;
};
26
mahesh

アンダースコアjs

_.uniq([1, 2, 1, 3, 1, 4]); //=> [1, 2, 3, 4]
14
fguillen

2014年になりましたが、時間の複雑さは依然として重要です!

array.filter(function() {
  var seen = {};
  return function(element, index, array) {
    return !(element in seen) && (seen[element] = 1);
  };
}());

http://jsperf.com/array-filter-unique/1

13
OhJeez
function array_unique(arr) {
    var result = [];
    for (var i = 0; i < arr.length; i++) {
        if (result.indexOf(arr[i]) == -1) {
            result.Push(arr[i]);
        }
    }
    return result;
}

組み込み関数ではありません。製品リストにアイテムが含まれていない場合は、一意のリストに追加して一意のリストを返します。

9
Raekye

行くぞ!どういたしまして!

Array.prototype.unique = function()
{
    var tmp = {}, out = [];
    for(var i = 0, n = this.length; i < n; ++i)
    {
        if(!tmp[this[i]]) { tmp[this[i]] = true; out.Push(this[i]); }
    }
    return out;
}

var a = [1,2,2,7,4,1,'a',0,6,9,'a'];
var b = a.unique();
alert(a);
alert(b);
6
Julius Loa

ここで、あらゆる種類の配列固有の実装を見つけることができます。

http://jsperf.com/distinct-hash-vs-comparison/12

http://jsperf.com/array-unique-functional

私は次のような機能的なスタイルを好む:

var arr = ['lol', 1, 'fdgdfg', 'lol', 'dfgfg', 'car', 1, 'car', 'a', 'blah', 'b', 'c', 'd', '0', '1', '1', '2', '3', '3', '3', 'crazy', 'moot', 'car', 'lol', 1, 'fdgdfg', 'lol', 'dfgfg', 'car', 1, 'car', 'a', 'blah', 'b', 'c', 'd', '0', '1', '1', '2', '3', '3', '3', 'crazy', 'moot', 'car', 'lol', 1, 'fdgdfg'];

var newarr = arr.reduce(function (prev, cur) {
    //console.log(prev, cur);
    if (prev.indexOf(cur) < 0) prev.Push(cur);
    return prev;
}, []);

var secarr = arr.filter(function(element, index, array){
    //console.log(element, array.indexOf(element), index);
    return array.indexOf(element) >= index;
});

//reverses the order
var thirdarr = arr.filter(function (e, i, arr) {
    //console.log(e, arr.lastIndexOf(e), i);
    return arr.lastIndexOf(e) === i;
});

console.log(newarr);
console.log(secarr);
console.log(thirdarr);
3
CMCDragonkai

別のアプローチは、配列情報の初期保存にオブジェクトを使用することです。その後、元に戻します。例えば:

var arr = ['0','1','1','2','3','3','3'];
var obj = {};

for(var i in arr) 
    obj[i] = true;

arr = [];
for(var i in obj) 
    arr.Push(i);

変数 "arr"には[[0]、 "1"、 "2"、 "3"、 "4"、 "5"、 "6"]が含まれるようになりました

1
Jason Graves

冗長な「戻り」配列、ECMA5(私は確信していません!)はなく、読みやすいです。

function removeDuplicates(target_array) {
    target_array.sort();
    var i = 0;

    while(i < target_array.length) {
        if(target_array[i] === target_array[i+1]) {
            target_array.splice(i+1,1);
        }
        else {
            i += 1;
        }
    }
    return target_array;
}
1
Amiga500Kid

Array。から重複した値を削除する方法は次のとおりです。

function ArrNoDupe(dupArray) {
   var temp = {};
    for (var i = 0; i < dupArray.length; i++) {
         temp[dupArray[i]] = true;
         var uniqueArray = [];
       for (var k in temp)
           uniqueArray.Push(k);
 return uniqueArray;
    }
}
1

これは動作します。それを試してみてください。

function getUnique(a) {
  var b = [a[0]], i, j, tmp;
  for (i = 1; i < a.length; i++) {
    tmp = 1;
    for (j = 0; j < b.length; j++) {
      if (a[i] == b[j]) {
        tmp = 0;
        break;
      }
    }
    if (tmp) {
      b.Push(a[i]);
    }
  }
  return b;
}
1
Darshan
function array_unique(nav_array) {
    nav_array = nav_array.sort(function (a, b) { return a*1 - b*1; });      
    var ret = [nav_array[0]];       
    // Start loop at 1 as element 0 can never be a duplicate
    for (var i = 1; i < nav_array.length; i++) { 
        if (nav_array[i-1] !== nav_array[i]) {              
            ret.Push(nav_array[i]);             
        }       
    }
    return ret;     
}
1
NaveenDAlmeida

これを使うのが好きです。 forループを使用しても何も問題はありません。組み込み関数を使用するのが好きです。型キャストまたは非型キャストのマッチングのためにブール引数を渡すこともできます。その場合、forループを使用します(filter()メソッド/関数はタイプキャストのマッチング(===)を行います)

Array.prototype.unique =
function()
{
    return this.filter(
        function(val, i, arr)
        {
            return (i <= arr.indexOf(val));
        }
    );
}
1
DrunkenBeetle

Googleクロージャーライブラリを使用しているユーザーは、goog.array.removeDuplicatesを自由に使用できます。これは、uniqueと同じです。ただし、配列自体は変更されます。

0
akond