Merge n object from array into one array based on id

元气小坏坏 提交于 2019-11-27 09:04:05

问题


I'm trying to merge n objects from an array of objects listed below.

I tried to use reduce method, but I can't understand what I'm doing wrong, still new to advance js methods.

  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;
    }, {})
  );

I'm trying to get something like this in a end, but I'm pretty lost.

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

回答1:


In your code, if you already have a r[id], you didn't assign the rest values. So change it like this:

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;
  }, {})
);



回答2:


Here's one way that combines map, reduce, and entries Array methods.

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);



回答3:


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));



回答4:


Assuming an array of objects with ids, I've done this often and it's just two steps.

  1. group by id to create an index. (_.groupBy is from underscorejs but a common op)
  2. pluck the values from the index.
    Object.vals(_.groupBy(arr, function(item){
      return item.id;
    }))

From an FP perspective, do one thing at a time to get the data into a shape that the next step can readily use. Don't try to do two things at once.



来源:https://stackoverflow.com/questions/58966177/merge-n-object-from-array-into-one-array-based-on-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!