0

Besides the horrible name of the question my question is quite simple. I have this object:

let test = {
  date1: [
    {
      time: 1,
      value: 5,
    },
    {
      time: 2,
      value: 6,
    },
  ],
  date2: [
    {
      time: 1,
      value: 20,
    },
    {
      time: 2,
      value: 10,
    },
  ],
};

That I want to transform to something like this:

let result = {
  date1: {
    values: [5, 6],
    times: [1, 2],
  },
  date2: {
    values: [1, 2], // easier to summarise?!
    times: [10, 20],
  },
};

I actually want to do this in order to summarise the value-values for each date. I thought that if I have them in an array it would be easier to summarise them. I know there are other forms to do this (and I'd be happy to see any solutions).

My current approach does not what I want it to do. It looks like this:

let keys = Object.keys(test);
let red = keys.reduce((acc, curr) => {
  return (acc[curr] = test[curr].map((e) => e.value));
}, {});

console.log(`red: `, red);

And produces this:

red: [ 20, 10 ]

4 Answers 4

2

This

return (acc[curr] = test[curr].map((e) => e.value));

is equivalent to

acc[curr] = test[curr].map((e) => e.value);
return acc[curr];

going inside a nested key of the accumulator on every iteration - which isn't the logic you want. Return the whole accumulator on a separate line, so previously assigned values don't get lost, and you also need to account for both the time and value properties of the array being iterated over - your => e.value only extracts one of the two properties you want.

let test = {
  date1: [
    {
      time: 1,
      value: 5,
    },
    {
      time: 2,
      value: 6,
    },
  ],
  date2: [
    {
      time: 1,
      value: 20,
    },
    {
      time: 2,
      value: 10,
    },
  ],
};

const keys = Object.keys(test);
const result = keys.reduce((acc, key) => {
  acc[key] = {
    values: test[key].map(({ value }) => value),
    times: test[key].map(({ time }) => time),
  };
  return acc;
  return acc;
}, {});

console.log(result);

or do

let test = {
  date1: [
    {
      time: 1,
      value: 5,
    },
    {
      time: 2,
      value: 6,
    },
  ],
  date2: [
    {
      time: 1,
      value: 20,
    },
    {
      time: 2,
      value: 10,
    },
  ],
};

const result = Object.fromEntries(
  Object.entries(test).map(([key, arr]) => [
    key,
    {
      values: arr.map(({ value }) => value),
      times: arr.map(({ time }) => time),
    }
  ])
);
console.log(result);

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

Comments

1

Try modifying it a little like this:

let result = Object.keys(test).reduce((acc, key) => {
        test[key].forEach((item) => {
            acc.push({
            date: key,
            time: item.time,
            value: item.value,
            });
        });
        return acc;
        }
    , []);
    console.log(result);

Comments

1

Assuming all inner objects have the same keys and no date array is empty:

let test = {date1:[{time:1,value:5},{time:2,value:6},],date2:[{time:1,value:20},{time:2,value:10},]};

let keys = Object.keys(test);
let red = keys.reduce((acc, curr) => ({
  ...acc,
  [curr]: Object.keys(test[curr][0])
                .reduce((acc, key) => ({
                  ...acc,
                  [key + 's']: test[curr].map(o => o[key])
                }), {})
}), {});

console.log(`red: `, red);

Comments

1

There is no need to first create arrays when you want to sum up values from different objects. It looks like you want to achieve this result:

{
  date1: 11
  date2: 30
}

The idea to use reduce is fine (for summing up values). You can use Object.entries and Object.fromEntries on top of that, in order to create the new object structure:

const test = {date1: [{time: 1,value: 5,},{time: 2,value: 6,},],date2: [{time: 1,value: 20,},{time: 2,value: 10,},],};

const result = Object.fromEntries(
    Object.entries(test).map(([key, arr]) => 
        [key, arr.reduce((sum, {value}) => sum + value, 0)]
    )
);

console.log(result);

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.