简体   繁体   English

通过键 javascript 合并/加入两个或多个 arrays 对象的方法

[英]Method to merge / join two or more arrays of objects by key javascript

I am trying to merge two or more arrays but its not working as I am wanting.我正在尝试合并两个或更多 arrays 但它无法正常工作。

I have two arrays arrCustomer and arrCustomerDetails.我有两个 arrays arrCustomer 和 arrCustomerDetails。 Both arrays have CustomerID as a key but I am wanting all values from arrCustomerDetails with merged in properties from the array arrCustomer. arrays 都将 CustomerID 作为键,但我希望 arrCustomerDetails 中的所有值都合并到数组 arrCustomer 的属性中。 I tried using _merge but its giving my only the count of the arrCustomer.我尝试使用 _merge 但它只给出了 arrCustomer 的计数。

Example:例子:

const arrCustomer = [
    { id: 1, name: "a" },
    { id: 2, name: "b" },
    { id: 3, name: "c" }
];

const arrCustomerDetail = [
    { id: 1, location: "jupiter", group: "C" },
    { id: 1, location: "venus", group: "G" },
    { id: 2, location: "mars", group: "D" }
];

const expecteResult = [
    { id: 1, name: "a", location: "jupiter", group: "C" },
    { id: 1, name: "a", location: "venus", group: "G" },
    { id: 2, name: "b", location: "mars", group: "D" },
    { id: 3, name: "c"  location: "", group: "" }
]

This works but its slow:这有效但速度很慢:

 let combinedData = [];
      arrCustomerDetail.map((element) => {
        combinedData.push({
          ...element,
          ...arrCustomer.find(
            (customer) => customer.id=== element.id
          ),
        });
      });

      arrCustomer.map((customer) => {
        if (
          combinedData.findIndex(
            (detail) => detail.id=== customer.id
          ) === -1
        )
          combinedData.push({
            ...customer,
          });
      });

Thanks all谢谢大家

( Join / Merge / Combine ) multiple arrays of objects combined by key. (加入/合并/组合)多个 arrays 对象通过键组合。

Update , it is also possible to make this join at run time for more than one array.更新,也可以在运行时为多个数组进行此连接。 you just need to define a primary matrix and create a filter on a matrix of matrices, follow this example in.你只需要定义一个主矩阵并在矩阵矩阵上创建一个过滤器,按照这个例子。

I hope this example helps, it worked perfectly, for the examples you gave, just edit the example below and you will see the result, I even made a joke doing the merging of everything and it worked correctly.我希望这个例子能有所帮助,它工作得很好,对于你给出的例子,只需编辑下面的例子,你就会看到结果,我什至开了个玩笑,合并了所有东西,它工作正常。 Remembering that it will always look at a primary matrix as a base.请记住,它将始终将主矩阵视为基础。

 "use strict"; const arrCustomer1 = [ { id: 1, name: "a" }, { id: 2, name: "b" } ]; const arrCustomerDetail1 = [ { id: 1, location: "jupiter", group: "C" }, { id: 2, location: "mars", group: "D" } ]; const wantedArray1 = [ { id: 1, name: "a", location: "jupiter", group: "C" }, { id: 2, name: "b", location: "mars", group: "D" } ]; const arrCustomer2 = [ { id: 1, name: "a" }, { id: 2, name: "b" }, { id: 3, name: "c" } ]; const arrCustomerDetail2 = [ { id: 1, location: "jupiter", group: "C" }, { id: 2, location: "mars", group: "D" } ]; const wantedArray2 = [ { id: 1, name: "a", location: "jupiter", group: "C" }, { id: 2, name: "b", location: "mars", group: "D" }, { id: 3, name: "c" } //or blanks for the other fields location group ]; const arrCustomer3 = [ { id: 1, name: "a" }, { id: 2, name: "b" }, { id: 3, name: "c" } ]; const arrCustomerDetail3 = [ { id: 1, location: "jupiter", group: "C" }, { id: 1, location: "venus", group: "G" }, { id: 2, location: "mars", group: "D" } ]; const wantedArray3 = [ { id: 1, name: "a", location: "jupiter", group: "C" }, { id: 1, name: "a", location: "venus", group: "G" }, { id: 2, name: "b", location: "mars", group: "D" }, { id: 3, name: "c" } //or blanks for the other fields location group ]; const combinedArrays = [arrCustomerDetail1, wantedArray1, arrCustomer2, arrCustomerDetail2, wantedArray2, arrCustomer3, arrCustomerDetail3, wantedArray3]; function joinArrByKey(primaryArr, combinedArrays, key) { return primaryArr.map((eArr1) => { const filter = new Array().concat.apply([], combinedArrays).filter((eArr2) => eArr2.id === eArr1[key]); return filter.length? Object.assign({}, eArr1, ...filter): eArr1; }); } console.log(joinArrByKey(arrCustomer1, combinedArrays, 'id')); console.log(joinArrByKey(arrCustomer2, combinedArrays, 'id')); console.log(joinArrByKey(arrCustomer3, combinedArrays, 'id'));

( Join / Merge / Combine ) Only for two arrays by key id, faster. ( Join / Merge / Combine ) 只针对两个 arrays by key id,速度更快。

you can create your own function like this and share it with all applications, instead of using _lodash.您可以像这样创建自己的 function 并与所有应用程序共享,而不是使用 _lodash。

 "use strict"; const arr1 = [ { id: 1, name: "a" }, { id: 2, name: "b" }, ]; const arr2 = [ { id: 1, price: 10 }, { id: 2, price: 20 }, ]; function joinArrById(primaryArr, secondArray) { return primaryArr.map((eArr1) => { const find = secondArray.find((eArr2) => eArr2.id === eArr1.id); return find? Object.assign(Object.assign({}, eArr1), find): eArr1; }); } console.log(joinArrById(arr1, arr2));

If the solution above doesn't suit you, a solution with _lodash.如果上述解决方案不适合您,请使用 _lodash 的解决方案。

import * as _ from "lodash";

const arr1 = [
  { id: 1, name: "a" },
  { id: 2, name: "b" },
];
const arr2 = [
  { id: 1, price: 10 },
  { id: 2, price: 20 },
];

var arrJoin = _.map(arr1, (obj: { id: number }) => {
  return _.assign(
    obj,
    _.find(arr2, {
      id: obj.id,
    })
  );
});

console.log(arrJoin);

Lodash doesn't really support merging lists together and keying off an object property to do so. Lodash 并不真正支持将列表合并在一起并关闭 object 属性来这样做。 I would do something like this, and roll my own merge() function.我会做这样的事情,然后滚动我自己的merge() function。

[Note: this merge() function runs in linear time — O(n).] [注意:此merge() function 以线性时间运行 — O(n)。]

const _ = require('lodash');

function merge(selectKey, keyComparer, ...lists) {
  const map = new Map();

  for (const list of lists) {
    for (const item of list) {

      const key = selectKey(item);
      let value = map.get(key);

      if (value === undefined) {
        map.set(key, [item]);
      }
      else {
        value.push(item);
      }
    }
  }

  const merged = Array.from(map.keys())
    .sort(keyComparer)
    .map( k => _.merge( {}, ...map.get(k) ) );
  return merged;
}

where * selectKey is a function that is passed an object and returns its key, and * keyComparer is a function that accepts two keys, x and y and returns a numeric indication of whether x is less than, equal to, or greater than `y'.其中 * selectKey是一个 function,它传递一个 object 并返回它的键,* keyComparer是一个 function,它接受两个键xy ,并返回一个数字指示,指示x是小于、等于还是大于 `y '. The convention is that惯例是

  • return values < 0 indicate that x is less than y返回值 < 0 表示x小于y
  • return values of 0 indicate that x and y are equal返回值 0 表示xy相等
  • return values > 0 indicate x is greater than y返回值 > 0 表示x大于y

Once you have that, it's easy:一旦你有了它,就很容易了:

const arr1 = [
  { id: 1, name: 'a' },
  { id: 2, name: 'b' },
  { id: 3, name: 'c' },
];
const arr2 = [
  { id: 1, location: 'jupiter', group: 'C' },
  { id: 4, location: 'venus', group: 'E' },
  { id: 2, location: 'mars', group: 'D' },
];

const idComparer = (x, y) => Math.sign(x - y);
const selectKey = o => o.id;

const merged = merge(selectKey, idComparer, arr1, arr2 );

The return value here is这里的返回值为

[
  { id: 1 , name: "a" , location: "jupiter" , group: "C" } ,
  { id: 2 , name: "b" , location: "mars"    , group: "D" } ,
  { id: 3 , name: "c"                                    } ,
  { id: 4 ,             location: "venus"   , group: "E" } ,
]

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

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