0

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/

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I'm getting some babel problem with this code due resultItem[headersIndex] ??= {}; but I will find another way to do the same
if (!resultItem[headersIndex]) resultItem[headersIndex] = {};
1

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

2 Comments

I picked the other one because it was first, it has some explanation and this one has some undefined when no key is found on the initial array, but it gave me an idea to use. Thanks.
Edited for undefined. Glad it helped :)
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.