将数组中的对象属性设置为true / false,是否id与另一个对象数组中的id匹配

时间:2020-08-29 09:06:16

标签: javascript arrays object ecmascript-6

因此,首先,这是一个简单的代码片段,以演示我的确切意思以及我尝试过的内容。

let array_1 = [
    { id: 1, name: 'Peter'   },
    { id: 2, name: 'John'    },
    { id: 3, name: 'Andrew'  },
    { id: 4, name: 'Patrick' },
    { id: 5, name: 'Brian'   }
];

let array_2 = [
    { id:  1, name: 'not Peter'   },
    { id: 80, name: 'not John'    },
    { id:  3, name: 'not Andrew'  },
    { id: 40, name: 'not Patrick' },
    { id:  5, name: 'not Brian'   }
];

array_1.forEach(item_1 => {
    for (let i = 0; i < array_2.length; i++) {
        item_1.matches = array_2[i].id === item_1.id
    }
});

console.log('matched_array', array_1);

此处的目标是根据matches是否将array_1属性添加到true中的每个对象并将其设置为false / idid中的任何其他array_2匹配。

在当前示例中,matches属性的结果应如下所示:true - false - true - false - true。但是我当前的代码仅在数组的最后一个元素(array_1)中正确设置了此属性。 显然是因为我的代码不完全正确,而这就是我遇到的问题。

2 个答案:

答案 0 :(得分:3)

您可以首先使用reduce方法创建一个对象,然后将其用作哈希表以检查数组2中是否存在具有相同ID的元素。

let array_1=[{"id":1,"name":"Peter"},{"id":2,"name":"John"},{"id":3,"name":"Andrew"},{"id":4,"name":"Patrick"},{"id":5,"name":"Brian"}, {"id":6,"name":"Joe"}]
let array_2=[{"id":1,"name":"not Peter"},{"id":80,"name":"not John"},{"id":3,"name":"not Andrew"},{"id":40,"name":"not Patrick"},{"id":5,"name":"not Brian"}]

const o = array_2.reduce((r, e) => (r[e.id] = true, r), {})
const result = array_1.map(e => ({ ...e, matches: o[e.id] || false}))
console.log(result)

答案 1 :(得分:1)

我将首先在Set中收集array_2的ID,集合具有O(1)查找时间,因此检查ID是否在该集合中的速度很快。然后遍历array_1,并使用has()检查创建的集合中是否存在ID。

let array_1 = [
    { id: 1, name: 'Peter'   },
    { id: 2, name: 'John'    },
    { id: 3, name: 'Andrew'  },
    { id: 4, name: 'Patrick' },
    { id: 5, name: 'Brian'   }
];

let array_2 = [
    { id:  1, name: 'not Peter'   },
    { id: 80, name: 'not John'    },
    { id:  3, name: 'not Andrew'  },
    { id: 40, name: 'not Patrick' },
    { id:  5, name: 'not Brian'   }
];

const array_2_ids = new Set(array_2.map(item_2 => item_2.id));
array_1.forEach(item_1 => item_1.matches = array_2_ids.has(item_1.id));

console.log('matched_array', array_1);


您当前的代码不起作用,因为for循环将为item_1.matches中的每个元素更新array_2属性。这意味着您每次都覆盖该属性。反过来,这将有效地导致仅item_1的最后一项检查array_2

要使您的代码正常运行,请执行以下操作:

array_1.forEach(item_1 => {
    for (let i = 0; i < array_2.length; i++) {
        item_1.matches = array_2[i].id === item_1.id
    }
});

应更改为此:

array_1.forEach(item_1 => {
    for (let i = 0; i < array_2.length; i++) {
        if (array_2[i].id === item_1.id) {
            item_1.matches = true;
            return;
        }
    }
    item_1.matches = false;
});