首页 > 解决方案 > 当我需要一个复合键来使其与众不同时,如何创建一个不同的 javascript 对象列表?

问题描述

是的,有几篇关于用多种语言创建不同列表的帖子,但我没有看到任何关于使用复合键或复合键的内容。

我有一个重复的对象(联系人)数组,我需要从中创建一个不同值的数组,键是电子邮件、姓名和电话字段的组合。对象如下所示:

{
    name: "Name",
    email: "email@example.com",
    phone: "5551212",
    organization: "BigCompany",
    title: "CEO"
}

我可以使用 map.has() 创建一个不同的列表,仅基于电子邮件:

const distinct = [];
const map = new Map();
for (const item of contacts) {
    if(!map.has(item.email)){
        map.set(item.email, true); // set any value, but add an entry to the Map
        distinct.push(item);
    }
}

...但是对于具有相同电子邮件但不同电话或相同电话但不同电子邮件等的每个联系人,我需要不同的数组元素。阅读有关文档map.has(),我没有看到任何关于关键参数的信息复杂的数据结构(在这种情况下是多个字段)。有没有更好的工具,或者我只是错过了文档的那一部分?

标签: javascriptarraysjavascript-objectsdistinct-values

解决方案


您可以创建一个 JSON 字符串用作键,如下所示:

const distinct = [];
const map = new Map();
for (const item of contacts) {
    const {name, email, phone} = item;
    const key = JSON.stringify({name, email, phone});
    if(!map.has(key){
        map.set(key, true);
        distinct.push(item);
    }
}

由于JSON.stringify( spec | MDN ) 需要遵循 ES2015 的属性顺序(许多操作不是),您知道如果每次都以相同的方式创建对象并且所有可枚举属性都是“自己的”属性,则结果对于具有相同name、、email和属性值的对象,JSON 字符串将是相同的phone(如果它们不同,则不同)。(“每次都以相同的方式创建对象”很重要,对象{a: 1, b: 2}{b: 2, a: 1}结果会产生不同的JSON 字符串。)


旁注:如果您只是使用map.hasand map.set(key, true), aSet可能更有意义:

const distinct = [];
const set = new Set();
for (const item of contacts) {
    const {name, email, phone} = item;
    const key = JSON.stringify({name, email, phone});
    if(!set.has(key){
        set.add(key);
        distinct.push(item);
    }
}

推荐阅读