繁体   English   中英

如果过滤键可以有任何类型的值,我如何过滤数组中的唯一对象?

[英]How do I filter the unique objects from an array if the filter key can have any type of value?

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
    }
]

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

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

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

output:

    [{
        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
    }]

您需要决定是什么让两个不同的对象“相等”。 在 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 代码链接

这将组合任何重复的键,创建一个新的属性values来保存组合值的数组(来自类似的键)。

 const array = [{key: 'A', value: 1},{key: 'A', value: 'str'},{key: 'C', value: { a: 1, b: '2'}},{key: 'B',value: true}] const arrayUniqueByKey = [array.reduce((b, a) => { let f = b.findIndex(c => c.key === a.key) if (f === -1) return [...b, a]; else { b[f].values = [...[b[f].value], a.value]; return b } }, [])]; console.log(arrayUniqueByKey)

您可以将Array.prototype.reduce()JSON.stringify( ) 结合使用,最后使用 Object.values ( ) 获取result数组

 const array = [{key: 'A',value: 1,},{key: 'A',value: 1,},{key: 'A',value: 'str',},{key: 'C',value: { a: 1, b: '2' },},{key: 'C',value: ['a', '2'],},{key: 'C',value: ['a', '2'],},{key: 'B',value: true}] const result = Object.values(array.reduce((a, c) => ((a[JSON.stringify(c)] = c), a), {})) console.log(result)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM