1

I have an array of objects like this:

[
  {
    p1: 1
    p2: 2
  },
  {
    p1: 3
    p2: 4
  }
]

I would like to flatten this into an array (maintaining order) for each property on the object:

[1, 3] and [2, 4]

Preferably these would be stored in a dictionary with the property as the key:

{
   p1: [1, 3],
   p2: [2, 4]
}

Is there a non brute force method of doing this in javascript? I am already using both jQuery and Underscore.js if those libraries are any help here.

My current plan is to iterate through all of the objects in the array and manually add each property value to its corresponding array. I'm interested to know if there is more interesting way of doing this.

10
  • There is no order to maintain, objects don't have order. Commented Jan 16, 2015 at 21:17
  • @adeneo But arrays do and I think the order in question is determined by the order of the objects within the array. Commented Jan 16, 2015 at 21:18
  • 1
    @muistooshort that is right, actually, good point. Commented Jan 16, 2015 at 21:27
  • 1
    yes, sorry if I was unclear, I would like the order within each property array to be determined by the order of the objects in the original array (as @muistooshort said) Commented Jan 16, 2015 at 21:28
  • 1
    Are all of these objects guaranteed to have the same properties? They will all have both p1 and p2? No p3, p4? None will have only p1 or p2? Commented Jan 16, 2015 at 21:34

2 Answers 2

2

If the properties are reliably the same on each object, you can use underscore like this.

var keys = _.keys(arr[0]);

var newObj = _.reduce(keys,function(obj,key){
   obj[key] = _.pluck(arr,key)
},{});
//newObj will now be in the requested format

If the properties are different on different objects, you'll need to do some additional logic to get the complete list of properties to iterate over.

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

3 Comments

Nice little optimization to use pluck there. The only issue would be if the objects had different keys, which, as far as we can tell, they do not.
Might be more natural to use reduce than separate initialization (var obj = { }) and iteration (_.each) steps.
in my case, the objects all have the same keys, so this looks excellent
2

Something like that:

var result = data.reduce(function(acc, x) {
  Object.keys(x).forEach(function(k) {
    acc[k] = (acc[k] || []).concat([x[k]])
  })
  return acc
},{})

console.log(result)
//^ {
//    p1: [1, 3],
//    p2: [2, 4]
//  }

But note that object keys have no order, and the result is up to each implementation. You may have to sort the resulting arrays if you need a specific order.

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.