Skip to content

Instantly share code, notes, and snippets.

@kyleshevlin
Last active February 10, 2017 11:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyleshevlin/d827b563e449aa8992e27a0592a35156 to your computer and use it in GitHub Desktop.
Save kyleshevlin/d827b563e449aa8992e27a0592a35156 to your computer and use it in GitHub Desktop.
Help me create a better 2d array, please

My request to the API returns an array of objects. I need to group each item in this array based on the value of one of its keys. Thus, I need to end up with a 2d array of arrays.

// API returns an array
const array = [
{ foreign_key: 1 },
{ foreign_key: 2 },
{ foreign_key: 1 },
{ foreign_key: 1 },
{ foreign_key: 3 },
{ foreign_key: 2 },
{ foreign_key: 3 },
{ foreign_key: 1 },
{ foreign_key: 2 },
{ foreign_key: 3 },
{ foreign_key: 3 },
{ foreign_key: 1 }
]
// Reduce to an object with keys of the foreign_key
const groupByForeignKeys = items.reduce((acc, cur) => {
if (!acc[cur.foreign_key]) {
acc[cur.foreign_key] = []
}
acc[cur.foreign_key].push(cur)
return acc
}, {})
// Create our empty 2d array
let twoDArray = []
// For each key, push the value of arrays to our now 2d array
for (let key in groupByForeignKeys) {
twoDArray.push(groupByForeignKeys[key])
}
// This is what I'm getting and expecting
// twoDArray === [
// [ { foreign_key: 1 }, { foreign_key: 1 }, { foreign_key: 1 }, { foreign_key: 1 } ],
// [ { foreign_key: 2 }, { foreign_key: 2 }, { foreign_key: 2 } ],
// [ { foreign_key: 3 }, { foreign_key: 3 }, { foreign_key: 3 }, { foreign_key: 3 } ]
// ]
@ThePaulMcBride
Copy link

What should the data look like when its done?

@kyleshevlin
Copy link
Author

kyleshevlin commented Feb 10, 2017

The data should end up looking like this:

const 2dArray = [
  [ { foreign_key: 1 }, { foreign_key: 1 }, { foreign_key: 1 }, { foreign_key: 1 } ],
  [ { foreign_key: 2 }, { foreign_key: 2 }, { foreign_key: 2 } ],
  [ { foreign_key: 3 }, { foreign_key: 3 }, { foreign_key: 3 }, { foreign_key: 3 } ]
]

@ThePaulMcBride
Copy link

ThePaulMcBride commented Feb 10, 2017

If all the keys are the same, does in need to be an array of objects, could it not be an array of strings/numbers?

@kyleshevlin
Copy link
Author

Well, these objects have other keys as well. I didn't want to write out full objects. The array I'm getting is a bunch of records from an API, so there are other keys like id, name, primary_image, etc.

@kyleshevlin
Copy link
Author

Looks like instead of for...in I can use Object.values(obj) to achieve my 2dArray in this case.

So it would be:

const twoDArray = Object.values(groupByForeignKeys)

@ThePaulMcBride
Copy link

I'd use lodash.

Something like this...

var result = _.groupBy(data, "foreign_key");

That will give you an object where the keys are the unique "foreign_key" values. Each one of those keys will be an array of objects that contain that key.

@kyleshevlin
Copy link
Author

That would be a good solution, too. Frankly, more legible than Object.values(), too. Thanks for your help, Paul.

@ThePaulMcBride
Copy link

So I think the overall solutions would look like this...

const _ = require('lodash');

const array = [
  { foreign_key: 1 },
  { foreign_key: 2 },
  { foreign_key: 1 },
  { foreign_key: 1 },
  { foreign_key: 3 },
  { foreign_key: 2 },
  { foreign_key: 3 },
  { foreign_key: 1 },
  { foreign_key: 2 },
  { foreign_key: 3 },
  { foreign_key: 3 },
  { foreign_key: 1 }
];

const groupByForeignKeys = _.groupBy(array, "foreign_key");

const twoDArray = Object.values(groupByForeignKeys);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment