3

I have an array of objects that looks like this:

[
     {
      key1: val_1.a
      key2: val_2.a
      key3: val_3.a
     },{
      key1: val_1.b
      key2: val_2.b
      key3: val_3.b
     },{
      key1: val_1.c
      key2: val_2.c
      key3: val_3.c
     }
]

I want to use that object to create another object that looks like this:

{ 
    key1: [val_1.a, val_1.b, val_1.c]
    key2: [val_2.a, val_2.b, val_2.c]
    key3: [[val_3.a, val_3.b, val_3.c]
}

Since the keys are the same in each object I just want to save in an array all the values that correspond to each key.

Please, If there is anyone who have had to do this before and could share the code it would be great. Thanks in advance.

0

4 Answers 4

8

You can do it like this in a way that will work in all browsers and will even work if all objects don't have the exact same set of keys (e.g. it will just accumulate data for whatever keys exist):

function combineKeyData(data) {
    var output = {}, item;
    // iterate the outer array to look at each item in that array
    for (var i = 0; i < data.length; i++) {
        item = data[i];
        // iterate each key on the object
        for (var prop in item) {
            if (item.hasOwnProperty(prop)) {
                // if this keys doesn't exist in the output object, add it
                if (!(prop in output)) {
                    output[prop] = [];
                }
                // add data onto the end of the key's array
                output[prop].push(item[prop]);
            }
        }
    }
    return output;
}

Working jsFiddle: http://jsfiddle.net/jfriend00/0jjquju9/

Explanation:

  1. For each item in the array
  2. For each key in an item in the array
  3. Add the key as an empty array to the output object if it doesn't already exist
  4. Add the data onto the end of the array for that key in the output object
  5. Return the resulting new object
Sign up to request clarification or add additional context in comments.

Comments

1
result = {};
for (var i = 0; i < array.length; i++) {
    var obj = array[i];
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (result[key]) {
                result[key].push(obj[key]);
            } else {
                retult[key] = [obj[key]];
            }
        }
    }
}

Comments

0

var arr = [
 {
  key1: 'val_1.a',
  key2: 'val_2.a',
  key3: 'val_3.a'
 },{
  key1: 'val_1.b',
  key2: 'val_2.b',
  key3: 'val_3.b'
 },{
  key1: 'val_1.c',
  key2: 'val_2.c',
  key3: 'val_3.c'
 }
]

var result = arr.reduce(function(obj, current) { //Reduce the array to an object
    Object.keys(current).forEach(function(key) { //Each key
        obj[key] = obj[key] || []; //Has to be an array if not exists
        obj[key] = Array.isArray(obj[key]) ? obj[key] : [obj[key]]; //Has to be an array if not an array
        obj[key].push(current[key]); //Add current item to array of matching key
    });
    return obj; //Continue to the next object in the array
});

console.log(result);

The above functions: Array#reduce, Array#forEach, Array.isArray, Object.keys are all part of the ECMAScript 5 specifications, as a result, they are not available in IE8 and below.

5 Comments

This returns a 2-dimensional array, he wants an object containing arrays.
This also assumes that all objects in the original array have exactly the same set of keys - no more no less. That's a shortcut that is true for the OP's exact data, but isn't the safest way to build the output data structure.
@jfriend00 And now it doesn't anymore.
If the result is going to make sense, it seems like that might be a necessity. Otherwise, the correspondence between the elements in the resulting sub-arrays will be wrong.
This is not good. What is value is null for example. You should your CODE op.
0
let R = require('ramda');
let arr =[
    {
     'key1': 'a',
     'key2': 'b',
     'key3': 'c',
    },{
     'key1': 'a1',
     'key2': 'b1',
     'key3': 'c1',
    },{
     'key1': 'a2',
     'key2': 'b2',
     'key3': 'c2',
    }
];

let key1 = R.pluck('key1', arr);
let key2 = R.pluck('key2', arr);
let key3 = R.pluck('key3', arr);
let obj = {
     key1,
     key2,
     key3
};

Obj = { key1: [ 'a', 'a1', 'a2' ], key2: [ 'b', 'b1', 'b2' ], key3: [ 'c', 'c1', 'c2' ] }

1 Comment

Perhaps you could explain your proposed solution, rather than just posting some code? - Found in review.

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.