Home > Back-end >  JavaScript, split object in 2, and push in array
JavaScript, split object in 2, and push in array

Time:02-17

I have an array of objects like this:

const arrayOfObjects = [
  { A: 1, B: 2, C: 3 },
  { A: 3, B: 4, C: 1 }
]

And another array which is called "headers"

const headers = [
  ['A', 'B'],
  ['C']
]

I have to create an array similar to the first one but, with those objects splited by what headers have in it's arrays.

This should be the goal:

const result = [
  [
    { A: 1, B: 2 },
    { C: 3 }
  ],
  [
    { A: 3, B: 4 },
    { C: 1 }
  ]
]

I tried by doing a "base" array with:

const baseArray = []
headers.forEach((header) => {
  const objFromHeader = {};
  header.forEach((head) => {
    objFromHeader[head] = 0;
  });
    baseArray.push(objFromHeader);
});

That will give me the result array but with 0 values for each key.

And then loop for the first array and put inside another array the base array with the correct values.

Then I wanted to fill each key according to the value that comes from arrayOfObjects but here is where I can't see how could I loop that array of objects and put the correct value. The only problem with that approach is that the result array will have some 0 values that come from the initiation array that I'm using, it would be better to me to only put the objects that actually have values and not 0 (I was thinking on another function to delete those keys with value = 0...)

How could I achieve it in a better way?

Fiddle:

https://jsfiddle.net/pmiranda/Lpscz6vt/

CodePudding user response:

When iterating over an object, use findIndex on the headers to identify which index in the headers array the property being iterated over should go into. Create an object there if it doesn't exist yet, and set the property.

const arrayOfObjects = [
  { A: 1, B: 2, C:3 },
  { A: 3, B: 4, C:1 }
];
const headers = [
  ['A', 'B'],
  ['C']
];

const toResultItem = (object) => {
  const resultItem = [];
  for (const [key, value] of Object.entries(object)) {
    const headersIndex = headers.findIndex(arr => arr.includes(key));
    resultItem[headersIndex] ??= {};
    resultItem[headersIndex][key] = value;
  }
  return resultItem;
};
console.log(arrayOfObjects.map(toResultItem));

CodePudding user response:

const arrayOfObjects = [
  { A: 1, B: 2, C: 3 },
  { A: 3, B: 4, C: 1 },
];
const headers = [['A', 'B'], ['C', 'D']];
const result = arrayOfObjects.map((obj) =>
  headers.map((header) =>
    header.reduce((acc, key) => {
      acc[key] = obj[key];
      return Object.keys(acc).reduce((newAcc, key) => {
        if (acc[key]) {
          newAcc[key] = acc[key];
        }
        return newAcc;
      }
        , {});
    }, {})
  )
);
console.log(result);

CodePudding user response:

Array.forEach implementation

Logic

  • Loop through arrayOfObjects array.
  • Inside that, loop through headers array.
  • Inside that, loop through each array in the headers array.
  • Create an empty object and assign the property from nodes in headers array with values from objects in arrayOfObjects array.

const arrayOfObjects = [
    { A: 1, B: 2, C: 3 },
    { A: 3, B: 4, C: 1 }
];

const headers = [
    ['A', 'B'],
    ['C']
];

const baseArray = []
arrayOfObjects.forEach((obj) => {
    const childNode = [];
    headers.forEach((head) => {
        const node = {};
        head.forEach((key) => node[key] = obj[key]);
        childNode.push(node);
    });
    baseArray.push(childNode);
});
console.log(baseArray)

Array.map and Array.reduce implementation.

Using the same logic implementes in the above solution, we can rewrite this using Array.map and Array.reduce as below.

const arrayOfObjects = [
    { A: 1, B: 2, C: 3 },
    { A: 3, B: 4, C: 1 }
];

const headers = [
    ['A', 'B'],
    ['C']
];

const output = arrayOfObjects.map((obj) => {
    return headers.map((header) => {
        return header.reduce((acc, curr) => {
            acc[curr] = obj[curr];
            return acc;
        }, {});
    })
})
console.log(output);

  • Related