首页 > 解决方案 > 用它的块(也是一个数组)更新一个数组,保持索引相同

问题描述

我处于需要使用其块更新现有数组以执行操作的情况。我有一个可行的解决方案,但我正在考虑性能,我需要知道我所拥有的是否足够好。

const parentArray = [
    {
    key: 0,
    customerId: 'customer 0',
    partyType: 'party 0',
    date: '2020-05-25T17:17:38.910Z',
  },
  {
    key: 1,
    customerId: 'customer 1',
    partyType: 'party 1',
    date: '2020-05-26T17:17:38.910Z',
  },
  {
    key: 2,
    customerId: 'customer 2',
    partyType: 'party 2',
    date: '2020-05-27T17:17:38.910Z',
  },
  {
    key: 3,
    customerId: 'customer 3',
    partyType: 'party 3',
    date: '2020-05-28T17:17:38.910Z',
  },
];

const childArray = [
    {
    key: 1,
    customerId: 'customer 01',
    partyType: 'party 01',
    date: '2020-05-25T17:17:38.910Z',
  },
  {
    key: 3,
    customerId: 'customer 21',
    partyType: 'party 21',
    date: '2020-05-27T17:17:38.910Z',
  },
];

const mergeArraysHandler = (parentArray, childArray, key) => {
    return parentArray.map((item, i) => {
      const record = childArray.find(record => record[key] === item[key]);
      if (record) {
        return record;
      }
      else {
        return item;
      }
    });
}

console.log(mergeArraysHandler(parentArray, childArray, 'key'));

如您所见,我有一个方法可以接收父数组、子数组和我用来运行检查的唯一道具。正如预期的那样,该方法将两个数组合并在一起,保持索引不变并更新作为父数组的现有数组。

标签: javascriptarrays

解决方案


不,它没有以良好的性能完成,不必要地你一次又一次地在子数组中搜索,而不是一次按键索引它。它可以轻松完成

const mergeArraysHandler = (parentArray, childArray, key) => {
  const childArrayMap = childArray.reduce((agg, v) => {
    agg[v[key]] = v
    return agg
  }) // or you can use lodash function _.keyBy instead of this

  return parentArray.map(item => childArrayMap(item[key]) || item))
}

或者使用 lodash 函数keyBy可以在一行中完成

const mergeArraysHandler = (parentArray, childArray, key) => 
  _.values({
    ..._.keyBy(parentArray, key), 
    ..._.keyBy(childArray, key)
  })

或者如果我们知道数组是按键排序的,那么最快的代码将是

const mergeArraysHandler = (parentArray, childArray, key) => {
    const arrays = [
       { array: parentArray, index: 0, value: parentArray[0] },
       { array: childArray, index: 0, value: childArray[0] },
    ]

    const res = []
    while (arrays.some(v => v.value)) {
       const ind = Number(arrays[1].value && arrays[0].value &&
         arrays[1].value[key] <= arrays[0].value[key])

       res.push(arrays[ind].value)
       const changes = ind && arrays[1].value[key] === arrays[0].value[key] ? [0, 1] : [ind]

       changes.forEach(ind => arrays[ind].value = arrays[ind].array[++arrays[ind].index])
    }

   return res
}

推荐阅读