根据ID将数组中的n个对象合并到一个数组中

时间:2019-11-21 02:07:36

标签: javascript arrays sorting reduce

我正在尝试合并下面列出的对象数组中的n个对象。

我尝试使用reduce方法,但是我不明白自己在做什么错,仍然是提高js方法的新手。

  const array = [
    {
      data: {
        '1': {
          foo: 'bar',
          test: true
        },
        '4': {
          foo: 'boor'
        }
      }
    },
    {
      data: {
        '1': {
          x: 'o',
          test2: false
        }
      }
    }
  ];

  const result = Object.values(
    array.reduce((r, { data }) => {
      Object.entries(data).forEach(([id, { ...else }]) => {
        r[id] = r[id] || {
          id,
          fooValue: else.foo, // edited
          x: else.x, // should be undefined for id `4`
          ...else
        };
      });
      return r;
    }, {})
  );

我试图最终得到这样的东西,但是我很迷茫。

  [
    {
      id: '1',
      foo: 'bar',
      test: true,
      x: 'o',
      test2: false
    },
    {
      id: '4',
      foo: 'boor'
    }
  ]

4 个答案:

答案 0 :(得分:1)

在您的代码中,如果您已经有一个r[id],则没有分配其余值。所以像这样更改它:

const result = Object.values(
  array.reduce((r, { data }) => {
    Object.entries(data).forEach(([id, { ...el }]) => {
      r[id] = {
        ...r[id], // this is the point
        id,
        ...el
      };
    });
    return r;
  }, {})
);

答案 1 :(得分:0)

这是结合map,reduce和Entry Array方法的一种方法。

const array = [
    {
      data: {
        '1': {
          foo: 'bar',
          test: true
        },
        '4': {
          foo: 'boor'
        }
      }
    },
    {
      data: {
        '1': {
          x: 'o',
          test2: false
        }
      }
    }
  ];
  
const merged = array.map(el => el.data).reduce((acc, el) => {
  Object.entries(el).forEach(([key, obj]) => {
    if(!acc[key]) acc[key] = {};
    acc[key] = { ...acc[key], ...obj };
  });
  return acc;
}, {});

const mergedArr = Object.entries(merged).reduce((acc, [key, obj]) => {
  acc.push({
    id: key,
    ...obj
  });
  return acc;
}, []);

console.log(mergedArr);

答案 2 :(得分:0)

var array = [
    {
        data: {
            '1': {
                foo: 'bar',
                test: true
            },
            '4': {
                foo: 'boor'
            }
        }
    },
    {
        data: {
            '1': {
                x: 'o',
                test2: false
            }
        }
    }
];

var mergedObject = [];
array.forEach(data => Object.keys(data.data).forEach(id => mergedObject = {
    ...mergedObject,
    [id]: {
        ...mergedObject[id],
        ...data.data[id]
    }
}))

console.log("mergedObject="+JSON.stringify(mergedObject));

var mergedArray = Object.keys(mergedObject).map(id => ({
    id,
    ...mergedObject[id]
}))

console.log("mergedArray="+JSON.stringify(mergedArray));

答案 3 :(得分:0)

假设一个带有ID的对象数组,我经常这样做,这只是两个步骤。

  1. 按ID分组以创建索引。 (_.groupBy来自underscorejs,但很常见)
  2. 从索引中提取值。
    Object.vals(_.groupBy(arr, function(item){
      return item.id;
    }))

从FP角度来看,一次执行一项操作即可将数据转换为便于下一步使用的形状。不要试图一次做两件事。