1

I have an array of objects I need transformed into an array of new objects. Is there a way this can be done without manually defining "texas" or "california" when defining the new array of objects?

This is my original data:

const data = [
    {
      year: "2005",
      texas: 6.984323232343243
    },
    {
      year: "2006",
      texas: 8.507629970573532
    },
    {
      year: "2005",
      california: 8.422823214889691
    },
    {
      year: "2006",
      california: 9.456857576876532
    }
  ];

And I need it to look like this:

const newData = [
    {
      year: 2005,
      texas: 6.984323232343243,
      california: 8.422823214889691
    },
    {
      year: 2006,
      texas: 8.507629970573532,
      california: 9.456857576876532
    }
  ];

I’ve attempted to group these objects and then ungroup, but I’ve only been able to group and can’t seem to figure out how to ungroup it the way I need. Is there a way I can do this without grouping it first?

const data = [
    {
      year: "2005",
      texas: 6.984323232343243
    },
    {
      year: "2006",
      texas: 8.507629970573532
    },
    {
      year: "2005",
      california: 8.422823214889691
    },
    {
      year: "2006",
      california: 9.456857576876532
    }
  ];
const groupByReduce = (array, key) => {
    return array.reduce((result, currentValue) => {
      (result[currentValue[key]] = result[currentValue[key]] || []).push(
        currentValue
      )
      return result
    }, {});
  };
const newData = groupByReduce(data, "year");

console.log(newData);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1
  • const groupedData = groupByReduce(data, 'year') Commented Jul 7, 2020 at 17:22

4 Answers 4

3

You can use reduce in such way-

const data = [
  {year: "2005", texas: 6.984323232343243},
  {year: "2006", texas: 8.507629970573532},
  {year: "2005", california: 8.422823214889691},
  {year: "2006", california: 9.456857576876532}
];

let res = data.reduce((a, c) => ({...a, [c.year]: {...a[c.year], ...c}}), {});

res = Object.values(res);

console.log(res);
.as-console-wrapper {min-height: 100%!important; top: 0}

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

1 Comment

Wow, this is awesome! I'm still learning how to fully use reduce. This is amazing and does exactly what I need, thank you!
2

Build an object with keys as year and aggregate the values.

const data = [
  {year: "2005", texas: 6.984323232343243},
  {year: "2006", texas: 8.507629970573532},
  {year: "2005", california: 8.422823214889691},
  {year: "2006", california: 9.456857576876532}
];

const convert = (arr, res = {}) => {
  arr.forEach((obj) => (res[obj.year] = { ...(res[obj.year] ?? {}), ...obj }));
  return Object.values(res);
};

console.log(convert(data));

Comments

0

You can modify your code to use Object.assign to merge objects, and Object.values to discard keys used for grouping:

const data = [
  {year: "2005", texas: 6.984323232343243},
  {year: "2006", texas: 8.507629970573532},
  {year: "2005", california: 8.422823214889691},
  {year: "2006", california: 9.456857576876532}
]

const groupByReduce = (array, key) => {
  return Object.values(array.reduce((result, currentValue) => (
    Object.assign(
      result[currentValue[key]] || (result[currentValue[key]] = {}),
      currentValue
    ),
    result
  ), {}))
}

console.log(groupByReduce(data, 'year'))

Comments

0

You can group all objects based upon their year, then merge all objects in a group together.

function groupBy(iterable, fn) {
  const groups = new Map();
  for (const item of iterable) {
    const key = fn(item);
    if (!groups.has(key)) groups.set(key, []);
    groups.get(key).push(item);
  }
  return groups;
}

const data = [
  { year: "2005", texas:      6.984323232343243 },
  { year: "2006", texas:      8.507629970573532 },
  { year: "2005", california: 8.422823214889691 },
  { year: "2006", california: 9.456857576876532 },
];

               // group objects based upon year
const result = Array.from(groupBy(data, obj => obj.year).values())
               // merge all objects in a group together
               .map(values => Object.assign({}, ...values));

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.