0

Any help would be appreciated.

I have an array (A) that contains 3 arrays of objects.

A = [
[{date: '2022-12-05', value: 10.6},{date: '2022-12-06', value: 5.6},{date: '2022-12-07, value: 8.6}],
[{date: '2022-12-05', value: 4.2},{date: '2022-12-06', value: 12.3},{date: '2022-12-07, value: 9.5}],
[{date: '2022-12-05', value: 5.6},{date: '2022-12-06', value: 9.8},{date: '2022-12-07, value: 7.8}]
]

From this array (A), I need to get an array (B) that will contain the merged/concatenated arrays with new / renamed object keys (value1,value2,value3) as per the following format:

B =  [
{date: '2022-12-05', value1: 10.6, value2: 4.2, value3: 5.6},
{date: '2022-12-06', value1: 5.6, value2: 12.3, value3: 9.8},
{date: '2022-12-07', value1: 8.6, value2: 9.5, value3: 7.8}
]

The length of the first array (A) may vary (1 / 2 / 3 or more), this is why I'm struggling to find a dynamic/efficient solution.

Many thanks

0

3 Answers 3

2

You could take a Map and collect all values.

const
    data = [[{ date: '2022-12-05', value: 10.6 }, { date: '2022-12-06', value: 5.6 }, { date: '2022-12-07', value: 8.6 }], [{ date: '2022-12-05', value: 4.2 }, { date: '2022-12-06', value: 12.3 }, { date: '2022-12-07', value: 9.5 }], [{ date: '2022-12-05', value: 5.6 }, { date: '2022-12-06', value: 9.8 }, { date: '2022-12-07', value: 7.8 }]],
    result = Array.from(
        data
            .flat()
            .reduce((m, { date, value }) => m.set(date, [...m.get(date) || [], value]), new Map),
        ([date, values]) => values.reduce((o, v, i) => ({ ...o, [`value${i + 1}`]: v }), { date })
    )
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

Comments

1

You could use map() and reduce() functions:

const A = [
  [{date: '2022-12-05', value: 10.6},{date: '2022-12-06', value: 5.6},{date: '2022-12-07', value: 8.6}],
  [{date: '2022-12-05', value: 4.2},{date: '2022-12-06', value: 12.3},{date: '2022-12-07', value: 9.5}],
  [{date: '2022-12-05', value: 5.6},{date: '2022-12-06', value: 9.8},{date: '2022-12-07', value: 7.8}]
];

const B = A.reduce((acc, curr) => {
  curr.forEach(item => {
    const existingItem = acc.find(i => i.date === item.date);
    if (existingItem) {
      existingItem[`value${A.indexOf(curr) + 1}`] = item.value;
    } else {
      acc.push({
        date: item.date,
        [`value${A.indexOf(curr) + 1}`]: item.value
      });
    }
  });
  return acc;
}, []);

console.log(B);

2 Comments

That is quick, thanks so much. I often struggle with this type of problem in JavaScript and React.js. How can I improve my programming skills, do you have any suggestions for me?
There is places, like leetcode, where you could practice such problems.
0

May i suggest a simpler data structure? Instead of numbering through the values in the form of 'value1, 'value2', ... 'valueN', you could use an array of values per date, which would make the transformation also a little bit easier as well:

const A = [
  [{date: '2022-12-05', value: 10.6},{date: '2022-12-06', value: 5.6},{date: '2022-12-07', value: 8.6}],
  [{date: '2022-12-05', value: 4.2},{date: '2022-12-06', value: 12.3},{date: '2022-12-07', value: 9.5}],
  [{date: '2022-12-05', value: 5.6},{date: '2022-12-06', value: 9.8},{date: '2022-12-07', value: 7.8}]
]

//Flatten Array
const Af = A.flat();

//Group by date
const B = Af.reduce((acc, cur) => {
  acc[cur['date']] = acc[cur['date']] ? [...acc[cur['date']], cur.value] : [cur.value]
  return acc;
}, {});

console.log(B);

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.