2

How do you group an array of objects by an object key to create a new array of objects based on the grouping? For example, I have an array of car objects:

const array = [
  {red: [ {height: 50} ]},
  {green: [ {height: 20} ]},
  {blue: [ {height: 30} ]},
  {blue: [ {height: 40} ]},
  {red: [ {height: 10} ]},
  {green: [ {height: 60} ]}
]

I want to create a new array of objects.(key is color)

const result = [
  {red: [{height: 50}, {height: 10}]},
  {green: [{height: 20}, {height: 60}]},
  {blue: [{height: 30}, {height: 40}]}
]

I tried to use lodash.groupBy, however I don't know how to solve this problem at all.

5
  • The first one is exactly doing what OP was asking suing lodash Commented Jan 14, 2019 at 8:12
  • @mplungjan all dupes seem to be grouping by key value, not key name. Commented Jan 14, 2019 at 8:13
  • Hey, It's not duplicate question. Look at my question carefully. Commented Jan 14, 2019 at 8:15
  • Im on mobile atm, but the trick would be to use Object.keys(item)[0] to get keyname for grouping purposes. Commented Jan 14, 2019 at 8:18
  • 1
    stackoverflow.com/a/40774906/295783 - seems very close to the accepted answer Commented Jan 14, 2019 at 8:26

2 Answers 2

6

Using array reduce you can iterate data and calculate result object.

const array = [
  { 'red': [ { height: 50 } ] },
  { 'green': [ { height: 20 } ] },
  { 'blue': [ { height: 30 } ] },
  { 'blue': [ { height: 40 } ] },
  { 'red': [ { height: 10 } ] },
  { 'green': [ { height: 60 } ] }
];

const res = array.reduce((acc, element) => {
  // Extract key and height value array
  const [key, heightValue] = Object.entries(element)[0];
  // Get or create if non-exist, and push height value from array, index 0
  (acc[key] || (acc[key] = [])).push(heightValue[0]);
  return acc;
}, {});

console.log(res);

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

1 Comment

Looks pretty much like one of the answers in the dupe I suggested stackoverflow.com/a/40774906/295783 - more elegant but very close
1

You can use lodash's _.mergeWith() to combine the objects with the same key, and then use _.map() to convert it back to an array:

const array = [{"red":[{"height":50}]},{"green":[{"height":20}]},{"blue":[{"height":30}]},{"blue":[{"height":40}]},{"red":[{"height":10}]},{"green":[{"height":60}]}]

const fn = _.flow([
  arr => _.mergeWith({}, ...arr, (o, s) => _.isArray(o) ? o.concat(s) : s),
  objs => _.map(objs, (v, k) => ({ [k]: v }))
])

const result = fn(array)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

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.