239

配列内の一意の値のリストを取得するにはどうすればよいですか? 常に 2 番目の配列を使用する必要がありますか、それとも JavaScript に Java のハッシュマップに似たものがありますか?

JavaScriptjQueryのみを使用します。追加のライブラリは使用できません。

4

20 に答える 20

134

@Rocketの回答のコメントでそれについて続けたので、ライブラリを使用しない例を提供することもできます。containsこれには、2 つの新しいプロトタイプ関数が必要です。unique

Array.prototype.contains = function(v) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] === v) return true;
  }
  return false;
};

Array.prototype.unique = function() {
  var arr = [];
  for (var i = 0; i < this.length; i++) {
    if (!arr.contains(this[i])) {
      arr.push(this[i]);
    }
  }
  return arr;
}

var duplicates = [1, 3, 4, 2, 1, 2, 3, 8];
var uniques = duplicates.unique(); // result = [1,3,4,2,8]

console.log(uniques);

contains信頼性を高めるために、MDN のindexOfshim に置き換えて、各要素indexOfが -1 に等しいかどうかを確認できます:ドキュメント

于 2012-06-28T14:58:50.147 に答える
33

EcmaScript 2016 を使用すると、このように簡単に実行できます。

 var arr = ["a", "a", "b"];
 var uniqueArray = Array.from(new Set(arr)); // Unique Array ['a', 'b'];

セットは常に一意であり、使用Array.from()するとセットを配列に変換できます。参考までに、ドキュメントを参照してください。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects /設定

于 2017-12-25T19:32:41.053 に答える
16

元の配列をそのまま残したい場合は、

最初の一意の要素を含めるには、2 番目の配列が必要です。

ほとんどのブラウザには次のものがありArray.prototype.filterます。

var unique= array1.filter(function(itm, i){
    return array1.indexOf(itm)== i; 
    // returns true for only the first instance of itm
});


//if you need a 'shim':
Array.prototype.filter= Array.prototype.filter || function(fun, scope){
    var T= this, A= [], i= 0, itm, L= T.length;
    if(typeof fun== 'function'){
        while(i<L){
            if(i in T){
                itm= T[i];
                if(fun.call(scope, itm, i, T)) A[A.length]= itm;
            }
            ++i;
        }
    }
    return A;
}
 Array.prototype.indexOf= Array.prototype.indexOf || function(what, i){
        if(!i || typeof i!= 'number') i= 0;
        var L= this.length;
        while(i<L){
            if(this[i]=== what) return i;
            ++i;
        }
        return -1;
    }
于 2012-06-28T14:48:26.907 に答える
8

Javascriptにはネイティブではありませんが、多くのライブラリにこのメソッドがあります。

Underscore.jsの_.uniq(array)リンク)は非常にうまく機能します(ソース)。

于 2012-06-28T14:29:52.620 に答える
5

jQuery を使用して、私が作成した Array 固有の関数を次に示します。

Array.prototype.unique = function () {
    var arr = this;
    return $.grep(arr, function (v, i) {
        return $.inArray(v, arr) === i;
    });
}

console.log([1,2,3,1,2,3].unique()); // [1,2,3]
于 2012-06-28T14:33:03.130 に答える
5

上記のソリューションの大部分は、実行時の複雑さが高くなります。

O(n)時間reduceでジョブを使用して実行できるソリューションを次に示します。

Array.prototype.unique = Array.prototype.unique || function() {
        var arr = [];
	this.reduce(function (hash, num) {
		if(typeof hash[num] === 'undefined') {
			hash[num] = 1; 
			arr.push(num);
		}
		return hash;
	}, {});
	return arr;
}
    
var myArr = [3,1,2,3,3,3];
console.log(myArr.unique()); //[3,1,2];

ノート:

このソリューションは、reduce に依存していません。アイデアは、オブジェクト マップを作成し、一意のものを配列にプッシュすることです。

于 2017-10-21T08:45:24.690 に答える
3

Array.some と Array.reduce で一意のものを見つけるには、バニラ JS だけが必要です。ES2015 構文では、わずか 62 文字です。

a.reduce((c, v) => b.some(w => w === v) ? c : c.concat(v)), b)

Array.some および Array.reduce は、IE9+ およびその他のブラウザーでサポートされています。ES2015 構文をサポートしていないブラウザーでサポートするように、通常の関数の太い矢印関数を変更するだけです。

var a = [1,2,3];
var b = [4,5,6];
// .reduce can return a subset or superset
var uniques = a.reduce(function(c, v){
    // .some stops on the first time the function returns true                
    return (b.some(function(w){ return w === v; }) ?  
      // if there's a match, return the array "c"
      c :     
      // if there's no match, then add to the end and return the entire array                                        
      c.concat(v)}),                                  
  // the second param in .reduce is the starting variable. This is will be "c" the first time it runs.
  b);                                                 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects /配列/削減

于 2015-12-06T00:36:47.093 に答える
1

純粋なJSでこの問題を試しました。次の手順に従いました 1.指定された配列をソートする 2.ソートされた配列をループする 3.前の値と次の値を現在の値で確認する

// JS
var inpArr = [1, 5, 5, 4, 3, 3, 2, 2, 2,2, 100, 100, -1];

//sort the given array
inpArr.sort(function(a, b){
    return a-b;
});

var finalArr = [];
//loop through the inpArr
for(var i=0; i<inpArr.length; i++){
    //check previous and next value 
  if(inpArr[i-1]!=inpArr[i] && inpArr[i] != inpArr[i+1]){
        finalArr.push(inpArr[i]);
  }
}
console.log(finalArr);

デモ

于 2017-04-01T11:49:42.757 に答える
0
Array.prototype.unique = function () {
    var dictionary = {};
    var uniqueValues = [];
    for (var i = 0; i < this.length; i++) {
        if (dictionary[this[i]] == undefined){
            dictionary[this[i]] = i;
            uniqueValues.push(this[i]);
        }
    }
    return uniqueValues; 
}
于 2016-01-22T14:33:39.437 に答える