简体   繁体   English

arrays 数组中的常用值 - lodash

[英]Common values in array of arrays - lodash

I have an array that looks like this:我有一个看起来像这样的数组:

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

I need to find common elements by id, and return them in an array that would look something like this:我需要通过 id 找到公共元素,并将它们返回到一个看起来像这样的数组中:

[
  {id: 1, name: 'Liam'},
  {id: 2, name: 'Oliver'},
]

If there isn't any way to do it with lodash, just JS could work too.如果没有任何方法可以使用 lodash,那么 JS 也可以。 Note that I do not know how many of these arrays I will have inside, so it should work for any number.请注意,我不知道里面有多少个 arrays,所以它应该适用于任何数量。

You can use lodash's _.intersectionBy() .您可以使用 lodash 的_.intersectionBy() You'll need to spread myArray because _intersectionBy() expect arrays as arguments, and not a single array of array:您需要传播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>

A vanilla solution can be as simple as a filter() call on the first element of the array checking to see that every() subsequent element contains some() elements that match.一个 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>

Nowadays vanilla ES is pretty powerful to work with collections in a functional way even without the help of utility libraries.如今,即使没有实用程序库的帮助,vanilla ES 也可以以功能方式与 collections 一起使用非常强大。 You can use regular Array 's methods to get a pure JS solution.您可以使用常规Array的方法来获得纯 JS 解决方案。 I've created two examples with pure JS.我用纯 JS 创建了两个示例。 Of course, there could be more approaches as well.当然,也可以有更多的方法。 And if you already use Lodash in your application, probably it would be better to just use its high-level implementation in form of _.intersectionBy() proposed above to reduce the code complexity.如果你已经在你的应用程序中使用了 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);

Use nested forEach loops and Set .使用嵌套的forEach循环和Set Go over each sub-array and find out the common items so far. 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.

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