web-dev-qa-db-ja.com

オブジェクト配列Javascriptの重複を削除する

オブジェクトの配列があります

_list = [{x:1,y:2}, {x:3,y:4}, {x:5,y:6}, {x:1,y:2}]
_

そして、私は効率的な方法を探しています(可能であればO(log(n)))重複を削除し、最終的には

_list = [{x:1,y:2}, {x:3,y:4}, {x:5,y:6}]
_

__.uniq_または__.contains_を試しましたが、満足のいく解決策が見つかりませんでした。

ありがとう!

編集:質問は別の質問の重複として識別されました。私は投稿する前にこの質問を見ましたが、オブジェクトの配列(2次元配列ではなく、アーロンに感謝します)であるため、私の質問には答えませんでした、または少なくとも他の質問の解決策は私の場合は機能しませんでした。

20
kwn

バニラJSバージョン:

const list = [{x:1,y:2}, {x:3,y:4}, {x:5,y:6}, {x:1,y:2}];

function dedupe(arr) {
  return arr.reduce(function(p, c) {

    // create an identifying id from the object values
    var id = [c.x, c.y].join('|');

    // if the id is not found in the temp array
    // add the object to the output array
    // and add the key to the temp array
    if (p.temp.indexOf(id) === -1) {
      p.out.Push(c);
      p.temp.Push(id);
    }
    return p;

    // return the deduped array
  }, {
    temp: [],
    out: []
  }).out;
}

console.log(dedupe(list));
13
Andy

Set を使用したプレーンJavaScript(ES2015)

const list = [{ x: 1, y: 2 }, { x: 3, y: 4 }, { x: 5, y: 6 }, { x: 1, y: 2 }];

const uniq = new Set(list.map(e => JSON.stringify(e)));

const res = Array.from(uniq).map(e => JSON.parse(e));

document.write(JSON.stringify(res));
22
isvforall

次を使用してみてください。

list = list.filter((elem, index, self) => self.findIndex(
    (t) => {return (t.x === elem.x && t.y === elem.y)}) === index)
16
Lava kumar N R

_Arrayr.prototype.reduce_メソッドと_Arrayr.prototype.some_メソッドの組み合わせをスプレッド演算子で使用します。

1。明示的な解決策。配列オブジェクトの完全な知識に基づいています。

_list = list.reduce((r, i) => 
  !r.some(j => i.x === j.x && i.y === j.y) ? [...r, i] : r
, [])
_

ここでは、比較されるオブジェクト構造に厳しい制限があります:_{x: N, y: M}_。そして、_[{x:1, y:2}, {x:1, y:2, z:3}]_は_[{x:1, y:2}]_にフィルターされます。

2。汎用ソリューション、JSON.stringify()。比較されるオブジェクトには、任意の数のプロパティを設定できます。

_list = list.reduce((r, i) => 
  !r.some(j => JSON.stringify(i) === JSON.stringify(j)) ? [...r, i] : r
, [])
_

このアプローチにはプロパティの順序に制限があるため、_[{x:1, y:2}, {y:2, x:1}]_はフィルタリングされません。

3。汎用ソリューション、Object.keys()。順序は関係ありません。

_list = list.reduce((r, i) => 
  !r.some(j => !Object.keys(i).some(k => i[k] !== j[k])) ? [...r, i] : r
, [])
_

このアプローチには別の制限があります。比較されるオブジェクトには同じキーのリストが必要です。したがって、明らかな違いがあるにもかかわらず、_[{x:1, y:2}, {x:1}]_はフィルタリングされます。

4。汎用ソリューション、Object.keys()+_.length_

_list = list.reduce((r, i) => 
  !r.some(j => Object.keys(i).length === Object.keys(j).length 
    && !Object.keys(i).some(k => i[k] !== j[k])) ? [...r, i] : r
, [])
_

最後のアプローチでは、オブジェクトはキーの数、キー自体、およびキー値によって比較されます。

Plunker を作成して遊んでみました。

6
dhilt

O(n)の一時オブジェクトに既にあるかどうかを確認した後、配列をフィルターします。

var list = [{ x: 1, y: 2 }, { x: 3, y: 4 }, { x: 5, y: 6 }, { x: 1, y: 2 }],
    filtered = function (array) {
        var o = {};
        return array.filter(function (a) {
            var k = a.x + '|' + a.y;
            if (!o[k]) {
                o[k] = true;
                return true;
            }
        });
    }(list);

document.write('<pre>' + JSON.stringify(filtered, 0, 4) + '</pre>');
4
Nina Scholz

以下が機能します:

var a = [{x:1,y:2}, {x:3,y:4}, {x:5,y:6}, {x:1,y:2}];

var b = _.uniq(a, function(v) { 
    return v.x && v.y;
})

console.log(b);  // [ { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 5, y: 6 } ]
1
chris p bacon