【问题标题】:Is there a good way to combine array and object in JavaScript?有没有一种在 JavaScript 中结合数组和对象的好方法?
【发布时间】:2019-07-11 07:00:48
【问题描述】:

有一个对象和一个数组。

list: [
  {
    oldData: {
      title: 'abc',
      id: 1,
      date: '1982-09-30',
      budget: 250000,
    },
    newData: [
      {
        key: 1,
        data: null,
        value: 5,
      },
      {
        key: 2,
        data: null,
        value: 22,
      },
      ...
    ],
  },
  {
    oldData: {
      title: 'blablablaaaaa',
      id: 2,
      date: '2012-02-23',
      budget: 350000,
    },
    newData: [
      {
        key: 1,
        data: null,
        value: 35,
      },
      {
        key: 2,
        data: null,
        value: 41,
      },
      ...
    ],
  },
  ... some more datas...
]

如上,同类型数据较多。

我需要同时使用oldData and newData,所以我想将两者结合起来。

如何组合oldData and newData,以便有多组oldData and newData pairs

例如,[{ combineData: {...} }, { combineData: {...} }, ... }] 这里。

我知道如何组合数组和数组,对象和对象,但我不知道怎么做。

有什么好的解决办法吗?

【问题讨论】:

  • const newList = list.map(x=> ({ combineData: {...x.oldData, ...x.newData }));
  • @NinaScholz 对不起,我编辑了问题帖。
  • @connexo 谢谢你,connexo!您的解决方案是尝试在新数组中映射和数据?

标签: javascript ecmascript-6


【解决方案1】:

您想要的结果不清楚,但您确实说过您想要新旧配对。这个答案与其他答案不同,它生成一个由旧/新对组成的组合数据对象数组,其中 oldData 值被复制,以便在其列表项中的每个对应 newData 值旁边出现。

您在第一个问题更新后的原始数据:

let list = [
   {
    oldData: { title: 'abc', id: 1, date: '1982-09-30', budget: 250000 },
    newData: [
      { key: 1, data: null, value: 5  },
      { key: 2, data: null, value: 22 },
      //...
    ],
  },
  {
    oldData: { title: 'blablablaaaaa', id: 2, date: '2012-02-23', budget: 350000 },
    newData: [
      { key: 1, data: null, value: 35 },
      { key: 2, data: null, value: 41 },
      //...
    ],
  },
  //... some more datas...
];

此代码将每个{old,new[]} 列表项映射到[{old,new}, {old,new}, ...] 对的数组中,这些数组在最终的reduce() 调用中组合:

var combinedDatas = list
    .map(listItem => listItem.newData.map(newItem => ({ 
        oldData: listItem.oldData, 
        newData: newItem 
    })))
    .reduce();

console.log(JSON.stringify(oldNewCombos, null, 4));

产生一个非规范化对的列表:

[
    { list[0].oldData, list[0].newData[0] }, 
    { list[0].oldData, list[0].newData[1] },
    //...rest of list[0] oldData with newData[n] combos

    { list[1].oldData, list[1].newData[0] }, 
    { list[1].oldData, list[1].newData[1] },
    //...rest of list[1] oldData with newData[n] combos

    { list[2].oldData, list[2].newData[0] }, 
    { list[2].oldData, list[2].newData[1] },
    //...rest of list[2] oldData with newData[n] combos

    //...
]

【讨论】:

    【解决方案2】:

    您可以在阵列上使用map()。并使用Object.assign()和扩展运算符将newData中所有元素的所有属性组合成一个对象。

    const arr = [
      {
        oldData: {
          a:10,
          b:20
        },
        newData: [
          {
            c:30,
            d:40
          },
          {
            e:50,
            f:60
          }
        ],
      }
    ]
    const res = arr.map(x => ({combinedData:{...x.oldData, ...Object.assign({}, ...x.newData)}}))
                   
    console.log(res)

    【讨论】:

    • 为什么要使用 Object.assign 和传播。对于传播,你可以这样做:{combinedData:{...x.oldData, ...x.newData}} 或者你不使用传播并使用 Object.assign 代替:{combinedData:Object.assign({},x.oldData, x.newData)}
    • @HMR x.newData 不是一个对象,它的 array 对象。
    • 看起来您正在使用 Object.assign 将 oldData 和 newData 属性组合成单个对象,使用解构的 newData 覆盖属性值。如果 newData 旨在以这种方式顺序覆盖属性,那么这是一个很好的解决方案。不过,这个问题要求“多组 oldData 和 newData 对”,我在回答中更从字面上解释了这一点。也许“对”的意思是像这样象征性地表示旧/新的单个对象组合!
    【解决方案3】:

    您可以映射数组并使用对象解构 (...object) 创建一个新的组合对象:

    const data = [
      {
        oldData: {
          foo: 'lorem',
        },
        newData: {
          bar: 'ipsum',
        },
      },
      {
        oldData: {
          foo: 'dolor',
        },
        newData: {
          bar: 'sit amet',
        },
      },
    ];
    
    const combined = data.map(record => ({...record.oldData, ...record.newData}));
    console.log(combined);

    然而,这将覆盖重复的键,所以类似于:

    {
      oldData: {
        message: 'a',
      },
      newData: {
        message: 'b',
      },
    }
    

    会变成:

    {
      message: 'b',
    }
    

    【讨论】:

    • newData 不是它的对象数组的对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 2018-09-04
    • 2018-07-17
    • 2020-11-06
    • 2013-12-12
    相关资源
    最近更新 更多