[英]Common values in array of arrays - lodash
我有一个看起来像这样的数组:
const myArray = [
[
{id: 1, name: 'Liam'},
{id: 2, name: 'Oliver'},
{id: 3, name: 'Jake'},
],
[
{id: 1, name: 'Liam'},
{id: 2, name: 'Oliver'},
{id: 4, name: 'Joe'},
],
]
我需要通过 id 找到公共元素,并将它们返回到一个看起来像这样的数组中:
[
{id: 1, name: 'Liam'},
{id: 2, name: 'Oliver'},
]
如果没有任何方法可以使用 lodash,那么 JS 也可以。 请注意,我不知道里面有多少个 arrays,所以它应该适用于任何数量。
您可以使用 lodash 的_.intersectionBy()
。 您需要传播myArray
,因为_intersectionBy()
期望 arrays 为 arguments,而不是单个数组数组:
const myArray = [[{"id":1,"name":"Liam"},{"id":2,"name":"Oliver"},{"id":3,"name":"Jake"}],[{"id":1,"name":"Liam"},{"id":2,"name":"Oliver"},{"id":4,"name":"Joe"}]] const result = _.intersectionBy(...myArray, 'id') console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>
一个 vanilla 解决方案可以像在数组的第一个元素上调用filter()
一样简单,检查every()
后续元素是否包含匹配的some()
元素。
const [srcElement, ...compArray] = [...myArray]; const intersection = srcElement.filter(o => ( compArray.every(arr => arr.some(p => p.id === o.id))) ); console.log(intersection)
.as-console-wrapper { max-height: 100%;important: top; 0; }
<script> const myArray = [ [{ id: 1, name: 'Liam' }, { id: 2, name: 'Oliver' }, { id: 3, name: 'Jake' }], [{ id: 1, name: 'Liam' }, { id: 2, name: 'Oliver' }, { id: 4, name: 'Joe' }], [{ id: 1, name: 'Liam' }, { id: 2, name: 'Oliver' }, { id: 5, name: 'Dean' }, { id: 6, name: 'Mara' }] ] </script>
如今,即使没有实用程序库的帮助,vanilla ES 也可以以功能方式与 collections 一起使用非常强大。 您可以使用常规Array
的方法来获得纯 JS 解决方案。 我用纯 JS 创建了两个示例。 当然,也可以有更多的方法。 如果你已经在你的应用程序中使用了 Lodash,那么最好只使用上面提出的_.intersectionBy()
形式的高级实现来降低代码复杂性。
const myArray = [
[
{id: 1, name: 'Liam'},
{id: 2, name: 'Oliver'},
{id: 3, name: 'Jake'},
],
[
{id: 1, name: 'Liam'},
{id: 2, name: 'Oliver'},
{id: 4, name: 'Joe'},
],
];
// Regular functional filter-reduce
const reducer = (accum, x) => {
return accum.findIndex(y => x.id == y.id) < 0
? [...accum, x]
: accum;
};
const resultFilterReduce = myArray
.flat()
.filter(x => myArray.every(y => y.findIndex(obj => obj.id === x.id) > -1))
.reduce(reducer, []);
console.log(resultFilterReduce);
// Filter-reduce with using of "HashMap" to remove duplicates
const resultWithHashMap = Object.values(
myArray
.flat()
.filter(x => myArray.every(y => y.findIndex(obj => obj.id === x.id) > -1))
.reduce((accum, x) => {
accum[x.id] = x;
return accum;
}, {})
);
console.log(resultWithHashMap);
使用嵌套的forEach
循环和Set
。 Go 遍历每个子阵列,找出迄今为止的共同项目。
const intersection = ([firstArr, ...restArr]) => { let common = new Set(firstArr.map(({ id }) => id)); restArr.forEach((arr) => { const newCommon = new Set(); arr.forEach(({ id }) => common.has(id) && newCommon.add(id)); common = newCommon; }); return firstArr.filter(({ id }) => common.has(id)); }; const myArray = [ [ { id: 1, name: "Liam" }, { id: 2, name: "Oliver" }, { id: 3, name: "Jake" }, ], [ { id: 1, name: "Liam" }, { id: 2, name: "Oliver" }, { id: 4, name: "Joe" }, ], [ { id: 2, name: "Oliver" }, { id: 4, name: "Joe" }, ], ]; console.log(intersection(myArray));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.