オブジェクトの配列があります
_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次元配列ではなく、アーロンに感謝します)であるため、私の質問には答えませんでした、または少なくとも他の質問の解決策は私の場合は機能しませんでした。
バニラ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));
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));
次を使用してみてください。
list = list.filter((elem, index, self) => self.findIndex(
(t) => {return (t.x === elem.x && t.y === elem.y)}) === index)
_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 を作成して遊んでみました。
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>');
以下が機能します:
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 } ]