2

I have the following structure

var nights = [
    { "2016-06-25": 32, "2016-06-26": 151, "2016-06-27": null },
    { "2016-06-24": null, "2016-06-25": null, "2016-06-26": null },
    { "2016-06-26": 11, "2016-06-27": 31, "2016-06-28": 31 },
];

And I want to transform it to:

{ 
    "2016-06-24": [null], 
    "2016-06-25": [32, null], 
    "2016-06-26": [151, null, 11], 
    "2016-06-27": [null, 31], 
    "2016-06-28": [31] 
}

What's the shortest way to solve this? I have no problems with using Underscore, Lodash or jQuery.

My current code is:

var out = {};
for (var i = 0; i < nights.length; i++) {
    for (var key in nights[i]) {
        if (out[key] === undefined) {
            out[key] = [];
        }
        out[key].push(nights[i][key]);
    }
}

It's similar to Convert array of objects to object of arrays using lodash but that has all keys present in each object.

4
  • What solution do you have? Commented Jun 23, 2016 at 10:09
  • Your object has error. You can't use - in key without " or '. Commented Jun 23, 2016 at 10:10
  • @DmitriPavlutin Looping over every object in turn, creating a new one. Too messy & dirty to post here, it's an embarrassment Commented Jun 23, 2016 at 10:11
  • @Tushar code added to the question Commented Jun 23, 2016 at 10:20

4 Answers 4

5

You can do it with the following snippet (no need for lodash etc):

const x = [{ '2016-06-25': 32, '2016-06-26': 151, '2016-06-27': null }, { '2016-06-24': null, '2016-06-25': null, '2016-06-26': null }, { '2016-06-26': 11, '2016-06-27': 31, '2016-06-28': 31 }, ];
let y = {};

x.forEach(obj => {
  Object.keys(obj).forEach(key => {
    y[key] = (y[key] || []).concat([obj[key]]);
  });
});

console.log(y)

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

3 Comments

When I run your snippet it gives me two errors as well as the answer (Chrome, latest)
Same error, appearing twice: { "message": "Script error.", "filename": "", "lineno": 0, "colno": 0 }
I cannot reproduce that, I'm sorry. A short google search though shows that there are other users having the same issue with the snippets in stackoverflow. Try running it in the browser's console by copy pasting. You should not get any error then (as this seems to be an issue with stackoverflow)
1

Here is my one-liner. Uses map to map keys into array of objects with properties of the keys. Then maps the original array to only that property and sets it as the value of the property. One issue with this way is that it will only use the properties of the first object in the array. So if other objects have properties that aren't in the first object they will be ignored.

const output = Object.assign({}, ...Object.keys(input[0]).map(props => ({[props]: input.map(prop => prop[props])})))

Edit: the output was in the wrong format, fixed

2 Comments

Welcome to SO! It's important to add some explanation to your code instead of just supplying a code-only answer.
Did my best its a little hard to explain
0

You could iterate over the array and the over the keys of the object and build a new object with the keys as new keys.

var data = [{ '2016-06-25': 32, '2016-06-26': 151, '2016-06-27': null }, { '2016-06-24': null, '2016-06-25': null, '2016-06-26': null }, { '2016-06-26': 11, '2016-06-27': 31, '2016-06-28': 31 }, ],
    result = {};

data.forEach(function (o) {
    Object.keys(o).forEach(function (k) {
        result[k] = result[k] || [];
        result[k].push(o[k]);
    });
});

console.log(result);

Comments

0

Used Typescript -- obviously you can remove the types while working in JavaScript.

Assumption: The array of objects coming into the function will always have the same kind and number of object keys

mapperArrayOfJsonsToJsonOfArrays(inputArrayOfJsons: any): any {
    if (inputArrayOfJsons.length > 0) {
        let resultMap = {};
        let keys: any[] = Object.keys(inputArrayOfJsons[0]);
        keys.forEach((key: any) => {
            resultMap[key] = [];
        });

        inputArrayOfJsons.forEach((element: any) => {
            let values: any[] = Object.values(element);
            let index = 0;
            values.forEach((value: any) => {
                resultMap[keys[index]].push(value);
                index = index + 1;
            });
        });
        return resultMap;
    }
    return {};
}

1 Comment

Wouldn't this remove types considering there were no generics used?

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.