web-dev-qa-db-ja.com

ES6-オブジェクトの配列から重複を削除する

次のようにオブジェクトの配列を想定します。

const listOfTags = [
    {id: 1, label: "Hello", color: "red", sorting: 0},
    {id: 2, label: "World", color: "green", sorting: 1},
    {id: 3, label: "Hello", color: "blue", sorting: 4},
    {id: 4, label: "Sunshine", color: "yellow", sorting: 5},
    {id: 5, label: "Hello", color: "red", sorting: 6},
]

ラベルと色が同じ場合、エントリが重複します。この場合、id = 1およびid = 5のオブジェクトは重複しています。

この配列をフィルタリングして重複を削除するにはどうすればよいですか?

私はあなたが1つのキーに対して次のようなものでフィルタリングできるソリューションを知っています:

const unique = [... new Set(listOfTags.map(tag => tag.label)]

しかし、複数のキーはどうですか?

コメントのリクエストに従って、ここで望ましい結果:

[
    {id: 1, label: "Hello", color: "red", sorting: 0},
    {id: 2, label: "World", color: "green", sorting: 1},
    {id: 3, label: "Hello", color: "blue", sorting: 4},
    {id: 4, label: "Sunshine", color: "yellow", sorting: 5},
]
12
Andy

Setをフィルターのクロージャーで使用できます。

const
    listOfTags = [{ id: 1, label: "Hello", color: "red", sorting: 0 }, { id: 2, label: "World", color: "green", sorting: 1 }, { id: 3, label: "Hello", color: "blue", sorting: 4 }, { id: 4, label: "Sunshine", color: "yellow", sorting: 5 }, { id: 5, label: "Hello", color: "red", sorting: 6 }],
    keys = ['label', 'color'],
    filtered = listOfTags.filter(
        (s => o => 
            (k => !s.has(k) && s.add(k))
            (keys.map(k => o[k]).join('|'))
        )
        (new Set)
    );

console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }
3
Nina Scholz

これに取り組むには、興味のあるプロパティに基づいた複合キーを使用して、これを一時的なマップに入れます。次に例を示します。

const foo = new Map();
for(const tag of listOfTags) {
  foo.set(tag.id + '-' tag.color, tag);
}
2
Evert

値を文字列に変換できるという仮定に基づいて、次を呼び出すことができます

_distinct(listOfTags, ["label", "color"])
_

ここで、distinctは次のとおりです。

_/**
 * @param {array} arr The array you want to filter for dublicates
 * @param {array<string>} indexedKeys The keys that form the compound key
 *     which is used to filter dublicates
 * @param {boolean} isPrioritizeFormer Set this to true, if you want to remove
 *     dublicates that occur later, false, if you want those to be removed
 *     that occur later.
 */
const distinct = (arr, indexedKeys, isPrioritizeFormer = true) => {
    const lookup = new Map();
    const makeIndex = el => indexedKeys.reduce(
        (index, key) => `${index};;${el[key]}`, ''
    );
    arr.forEach(el => {
        const index = makeIndex(el);
        if (lookup.has(index) && isPrioritizeFormer) {
            return;
        }
        lookup.set(index, el);
    });

    return Array.from(lookup.values());
};
_

傍注:distinct(listOfTags, ["label", "color"], false)を使用すると、次が返されます:

_[
    {id: 1, label: "Hello", color: "red", sorting: 6},
    {id: 2, label: "World", color: "green", sorting: 1},
    {id: 3, label: "Hello", color: "blue", sorting: 4},
    {id: 4, label: "Sunshine", color: "yellow", sorting: 5},
]
_
1
B12Toaster

1つの方法は、2つの値の組み合わせをキーとして使用し、現在のオブジェクトを値として使用するオブジェクト(またはマップ)を作成し、そのオブジェクトから値を取得することです

const listOfTags = [
    {id: 1, label: "Hello", color: "red", sorting: 0},
    {id: 2, label: "World", color: "green", sorting: 1},
    {id: 3, label: "Hello", color: "blue", sorting: 4},
    {id: 4, label: "Sunshine", color: "yellow", sorting: 5},
    {id: 5, label: "Hello", color: "red", sorting: 6},
]

const uniques = Object.values(
  listOfTags.reduce((a, c) => {
    a[c.label + '|' + c.color] = c;
    return a
  }, {}))

console.log(uniques)
1
charlietfl
const listOfTags = [
    {id: 1, label: "Hello", color: "red", sorting: 0},
    {id: 2, label: "World", color: "green", sorting: 1},
    {id: 3, label: "Hello", color: "blue", sorting: 4},
    {id: 4, label: "Sunshine", color: "yellow", sorting: 5},
    {id: 5, label: "Hello", color: "red", sorting: 6},
]

const unique = [];

listOfTags.map(x => unique.filter(a => a.label == x.label && a.color == x.color).length > 0 ? null : unique.Push(x));

console.log(unique);
1
COLBY BROOKS

ここでreduceを使用して、フィルターされたオブジェクトを取得できます。

listOfTags.reduce((newListOfTags, current) => {
    if (!newListOfTags.some(x => x.label == current.label && x.color == current.color)) {
        newListOfTags.Push(current);
    }
    return newListOfTags;
}, []);
0
Ankit Arya