【问题标题】:es6 merge two array of objects and override the existing objectes6 合并两个对象数组并覆盖现有对象
【发布时间】:2018-05-13 06:35:17
【问题描述】:

我有 2 个对象数组:

const arr1 = [{'id':'1' 'value':'yes'}, {'id':'2', 'value':'no'}];
const arr2 = [{'id':'2', 'value':'yes'}];

所以,如果我尝试合并这两个数组,结果应该是:

arrTemp = [{'id':'1', 'value':'yes'}, {'id':'2', 'value':'yes'}];

基本上,它应该类似于 Object.assign(),但无论我尝试什么,它都不起作用。有人可以帮我吗?

我修改了数据结构。现在是否可以合并它们并获得输出。

谢谢

【问题讨论】:

  • 你打算如何删除 {'2':'no'}?
  • 这个数据结构太丑了。
  • 为什么在每个对象中使用不同的键?

标签: javascript arrays merge ecmascript-6


【解决方案1】:

在这种情况下,数组reduce 可能会派上用场。请参见下面的示例:

[...arr1, ...arr2].reduce((acc, item) => {
  const updated = acc.find(a => a.id === item.id)
  if (!updated) {
    acc.push(item)
  } else {
    const index = acc.indexOf(updated)
    acc[index] = { ...item, ...acc[index] }
  }
  return acc
}, [])

【讨论】:

    【解决方案2】:

    这就是使用 ES6 spread、reduce 和 Object.values 完成工作的方法。

    const arr1 = [{
      'id': '1',
      'value': 'yes'
    }, {
      'id': '2',
      'value': 'no'
    }];
    const arr2 = [{
      'id': '2',
      'value': 'yes'
    }];
    
    const result = Object.values([...arr1, ...arr2].reduce((result, {
      id,
      ...rest
    }) => {
      result[id] = {
        ...(result[id] || {}),
        id,
        ...rest
      };
      return result;
    }, {}));
    
    console.log(result);

    【讨论】:

    • 这真的很棒,是最新的答案,谢谢分享!
    【解决方案3】:

    对于稍后找到此答案的任何人。有几种方法可以让它完全正常工作,但您可以过滤第一个数组中所有调整后的元素,然后将其与第二个数组组合。

    const arr3 = [...arr1.filter(item1 => !arr2.find(item2 => item1.id === item2.id)), ...arr2]
    

    或者,您可以更新第一个数组中的元素,然后从第二个数组中过滤它们。

    【讨论】:

      【解决方案4】:

      添加现有对象数组的简单方法:

      const arr1 = [{ "name":"John", "age":30, "car":"toyata" }];
      const arr2 = [{ "name":"Ales", "age":40, "car":"Nissan" }];
      Array.prototype.push.apply(arr1, arr2);
      
      Result:=>
      console.log(arr1)
      

      【讨论】:

        【解决方案5】:

        您可以将Map 作为结果数组中新分配对象的引用,并首先使用对象的副本构建一个新数组,然后迭代第二个数组并使用相同的键更新对象。

        var array1 = [{ 1: 'yes' }, { 2: 'no' }],
            array2 = [{ 2: 'yes' }],
            getKey = o => Object.keys(o)[0],
            map = new Map,
            result = array1.map(o => (k => map.set(k, Object.assign({}, o)).get(k))(getKey(o)));
        
        array2.forEach(o => Object.assign(map.get(getKey(o)), o));
        
        console.log(result);
        .as-console-wrapper { max-height: 100% !important; top: 0; }

        【讨论】:

          【解决方案6】:

          在 javascript 中,数组只是由从 0 开始的数字索引的对象。

          因此,当您在arr1arr2 上使用Object.assign 时,您将使用arr2 中的第一项覆盖arr1 中的第一项,因为它们都在键0 下被索引。

          您的结果将是:

          [
           { '2': 'yes' },
           { '2': 'no' }
          ]
          

          (或在对象语法中:)

          { 
           0: { '2': 'yes' },
           1: { '2': 'no' }
          }
          

          您可以创建一个以数字 string 为索引的对象,而不是使用数组(无论如何,这就是您对数组的看法)。

          因此您可以更改原始数据结构以使工作更轻松:

          const arr1 = {
            '1': 'yes',
            '2': 'no'
          };
          
          const arr2 = {
            '2': 'yes'
          };
          
          const result = Object.assign(arr1, arr2);
          

          【讨论】:

          • 那为什么不直接{ 1:"yes", 2:"false" }呢? 一般来说,在大多数情况下,我通常更喜欢在 javascript 中使用对象而不是数组。 -> 那是错误的方法。为正确的工作选择正确的。数组非常非常有用。
          • 这是一个非常大的对象数组。
          【解决方案7】:

          您可以使用有效的 ES6 数据结构,例如地图:

          const 1 = { 1: { string: 'yes' }, 2: { string: 'no' } } const 2 = { 2: { string: 'yes' }, 3: { string: 'no' } } const 3 = { ...1, ...2}

          这将用第二个参数覆盖您的第一个参数,或者在可能的情况下将它们组合起来。 只需在您的浏览器中尝试一下,它会更容易并提高性能,因为您永远不必使用 findById() 这是一项昂贵的操作。

          【讨论】:

          • findById() -> 那应该是什么?!而且标识符不能以数字开头!
          【解决方案8】:

          您不能使用 array.prototype 映射,因为 arr1 和 arr2 的键具有相同的值 '2'。

          你应该使用这样的东西

          for (var i = 0, l = arr1.length; i < l; i++) {
           var key = Object.keys(arr1[i]);
           if (!arr2[key]) { arr2[key] = []; }
           arr2[key].push(arr1[i][key]);
          }
          

          问候

          【讨论】:

            【解决方案9】:
            const result = Object.entries(Object.assign({}, ...arr1,...arr2)).map(([key, value]) => ({[key]:value}));
            

            您可以将数组 (...) 传播到一个结果对象中(通过 Object.assign),然后将 map 其条目再次传播到一个数组中。

            【讨论】:

            • 它抛出 uncaughtException: Unexpected token : 。我同意数据结构很丑,但现在不能改变它。
            • @ashy 抱歉,已修复;)
            猜你喜欢
            • 2021-07-07
            • 1970-01-01
            • 2014-01-02
            • 1970-01-01
            • 2017-02-04
            • 2018-11-23
            • 2019-10-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多