web-dev-qa-db-ja.com

JavaScriptで一意のアイテムのリストを作成するにはどうすればよいですか?

CouchDBのreduce関数で、アイテムのリストを一意のリストに減らす必要があります。

注:その場合、リストがあっても問題ありません。文字列型のアイテムが少数になります。

私の現在の方法は、オブジェクトのキーを設定してから、そのオブジェクトのキーを返すことです。これは、コードが_.uniqなどを使用できない場所だからです。

これよりもエレガントな綴り方を見つけたいと思います。

function(keys, values, rereduce) {
  // values is a Array of Arrays
  values = Array.concat.apply(null, values);
  var uniq = {};
  values.forEach(function(item) { uniq[item] = true; });
  return Object.keys(uniq);
}
12
Ronny

一般的に、使用したアプローチは良い考えです。しかし、アルゴリズムを大幅に高速化するソリューションを提案することはできます。

function unique(arr) {
    var u = {}, a = [];
    for(var i = 0, l = arr.length; i < l; ++i){
        if(!u.hasOwnProperty(arr[i])) {
            a.Push(arr[i]);
            u[arr[i]] = 1;
        }
    }
    return a;
}

ご覧のとおり、ここにはループが1つだけあります。

私はあなたと私のソリューションの両方をテストしている example を作成しました。それで遊んでみてください。

25
Eugene Naydenov

小さなリストに適した代替手段は、Unixコマンドラインアプローチのsort | uniqを類人猿にすることです。

    function unique(a) {
        return a.sort().filter(function(value, index, array) {
            return (index === 0) || (value !== array[index-1]);
        });
    }

この関数は、引数を並べ替えてから、結果をフィルタリングして、前の項目と等しい項目をすべて省略します。

キーベースのアプローチは問題なく、多数のアイテムに対してより優れたパフォーマンス特性を備えています(配列をソートするためのO(n log n)と比較して、ハッシュテーブルにn個のアイテムを挿入するためのO(n))。ただし、これは小さなリストでは目立たない可能性があります。さらに、このバージョンでは、必要に応じて別の並べ替え関数または等価関数を使用するように変更できます。ハッシュキーを使用すると、JavaScriptのキーの同等性の概念に固執します。

9
Rob Hague

最良の方法は、ES6とSetを使用することのようです。 fiddle によると、1行で上記よりも高速*

    
const myList = [1,4,5,1,2,4,5,6,7];
const unique = [...new Set(myList)];
    
console.log(unique);

*サファリでテスト済み

これは、文字列だけでなく、何でも機能するはずです。

export const getUniqueList =  (a: Array<any>) : Array<any> => {

  const set = new Set<any>();

  for(let v of a){
      set.add(v);
  }

  return Array.from(set);

};

上記は次のように減らすことができます。

export const getUniqueValues = (a: Array<any>) => {
   return Array.from(new Set(a));
};

:)

2
Alexander Mills

Object.keysを使用すると、整数引数(uniq([1,2,3])=> ['1'、 '2'、 '3']を入力すると、文字列が得られます。Array.reduceを使用したものは次のとおりです。

function uniq(list) {
    return list.reduce((acc, d) => acc.includes(d) ? acc : acc.concat(d), []);
}
0
JW Buitenhuis

これは古い質問です、私は知っています。しかし、それはいくつかのグーグル検索のトップにあるので、以下を使用して@RobHagueと@EugeneNaydenovからの回答を組み合わせることができることを追加したいと思いました:

function unique(arr) {
  const u = {};
  return arr.filter((v) => {
    return u[v] = !u.hasOwnProperty(v);
  });
};

次を追加することで、undefined値(多くの場合便利)を無視することもできます。

function unique(arr) {
  const u = {};
  return arr.filter((v) => {
    return u[v] = (v !== undefined && !u.hasOwnProperty(v));
  });
};

ここでこのソリューションを試すことができます: https://jsfiddle.net/s8d14v5n/

0
rwblackburn