首页 > 解决方案 > 如果过滤键可以具有任何类型的值,我如何过滤数组中的唯一对象?

问题描述

interface FormValues {
    key: string;
    value: any;
}

const array: FormValues[] = [
    {
        key: 'A',
        value: 1 // number
    },
    {
        key: 'A',
        value: 1 // number
    },
    {
        key: 'A',
        value: 'str' // string
    },
    {
        key: 'C',
        value: { a: 1, b: '2' } // object
    },
    {
        key: 'C',
        value: ['a','2'] // array
    },
    {
        key: 'C',
        value: ['a','2'] // array
    }
    {
        key: 'B',
        value: true // boolean
    }
]

我想根据 field 过滤对象value,它可以具有任何类型的值。

我试着这样做;我的解决方案不适用于嵌套对象检查。

const key = 'value';
const arrayUniqueByKey = [...new Map(array.map(item => [item[key], item])).values()];

输出 :

    [{
        key: 'A',
        value: 1 // number
    },
    {
        key: 'A',
        value: 'str' // string
    },
    {
        key: 'C',
        value: { a: 1, b: '2' } // object
    },
    {
        key: 'C',
        value: ['a','2'] // array
    },
    {
        key: 'B',
        value: true // boolean
    }]

标签: javascriptnode.jsarraystypescript

解决方案


您需要决定是什么让两个不同的对象“相等”。在 JavaScript 中,对象(包括数组)的所有内置比较都是通过引用进行的。这意味着因为['a','2'] === ['a','2']存在false两个不同的数组对象,尽管它们具有相同的内容。请参阅如何确定两个 JavaScript 对象的相等性?了解更多信息。

我将采取的方法是,如果两个值通过JSON.stringify()保证属性键顺序相同的修改版本序列化为相同的值,您希望它们被视为相等(因此{a: 1, b: 2}{b: 2, a: 1}无论它们如何,它们都将相等字符串化)。我使用这个答案的一个版本来做到这一点:

function JSONstringifyOrder(obj: any, space?: number) {
    var allKeys: string[] = [];
    var seen: Record<string, null | undefined> = {};
    JSON.stringify(obj, function (key, value) {
        if (!(key in seen)) {
            allKeys.push(key); seen[key] = null;
        }
        return value;
    });
    allKeys.sort();
    return JSON.stringify(obj, allKeys, space);
}

现在我可以用它来制作你的钥匙Map

const arrayUniqueByKey = [...new Map(array.map(
    item => [JSONstringifyOrder(item[key]), item]
)).values()];

您可以验证它的行为是否符合您的要求:

console.log(arrayUniqueByKey);
/* [{
  "key": "A",
  "value": 1
}, {
  "key": "A",
  "value": "str"
}, {
  "key": "C",
  "value": {
    "a": 1,
    "b": "2"
  }
}, {
  "key": "C",
  "value": [
    "a",
    "2"
  ]
}, {
  "key": "B",
  "value": true
}] */

Playground 代码链接


推荐阅读