简体   繁体   中英

JSON - array of objects into objects of arrays

I have a series of JSON entries:

[{"num": "1","name_A": "Alex" ,"name_B": "Bob"}, {"num": "2","name_A": "Anne" ,"name_B": "Barbra"}]

I am trying to convert this array of Objects as painlessly as possible into two objects - one with title name_A, and the second with the title name_B. Objects have to contain the title and an array of matching num-name pairs:

[{title: "name_A", names:[{"1", "Alex}, {"2", "Anne"}]}, {title:"name_B", names: [{"1", "Bob"}, {"2", "Barbra"}]}]

At first I tried simply to create two objects by reducing the array of object twice, once for name_A and second time for name_B and later glue everything together:

// get 'names' array
var name_A = objArray.reduce(function(memo, curr) {
    memo.push({curr.num, curr.name_A})
    return memo;
}, []);

But even this is failing. Why there is no push method for memo if I initialize reduce with an empty array?

And second question, am I on a right track or is there a better way to achieve this?

The problem with your code is that { curr.num, curr.name_A } is not a valid object, it's missing the property names. I've added properties num and name in my code below.

var name_A = [];
var name_B = [];
objArray.forEach(function(curr) {
    name_A.push({num: curr.num, name: curr.name_a});
    name_B.push({num: curr.num, name: curr.name_B});
});
var result = [ 
    { title: "name_A" }, names: name_A },
    ( title: "name_B" }, names: name_B }
];

Also, if you want to make an array out of the results of looping over an array, you should use .map rather than .reduce .

Comments inline, made a few minor corrections to the expectations.

var input = [{ "num": "1", "name_A": "Alex", "name_B": "Bob" }, { "num": "2", "name_A": "Anne", "name_B": "Barbra" }]

var output = input.reduce(function (a, b) {
    // construct new objects and set their properties
    var i = {};
    i[b.num] = b.name_A;
    var j = {};
    j[b.num] = b.name_B;

    // add them to our collection elements
    a[0].names.push(i);
    a[1].names.push(j);

    return a;
   // initializing our collection
}, [{ title: "name_A", names: [] }, { title: "name_B", names: [] }]);

// pretty print our output
console.log(JSON.stringify(output, null, "     "))

 var input = [{ "num": "1", "name_A": "Alex", "name_B": "Bob" }, { "num": "2", "name_A": "Anne", "name_B": "Barbra" }] var output = input.reduce(function (a, b) { // construct new objects and set their properties var i = {}; i[b.num] = b.name_A; var j = {}; j[b.num] = b.name_B; // add them to our collection elements a[0].names.push(i); a[1].names.push(j); return a; // initializing our collection }, [{ title: "name_A", names: [] }, { title: "name_B", names: [] }]); so.log(output) 
 <pre id="output"></pre> <script> var so = { log: function(o) { document.getElementById("output").innerHTML = JSON.stringify(o, null, " ") } } </script> 

Assuming only property num is fixed. All other properties are treated as data, like name_A or name_B .

 var a = [{ "num": "1", "name_A": "Alex", "name_B": "Bob" }, { "num": "2", "name_A": "Anne", "name_B": "Barbra" }], result = []; a.forEach(function (el) { var num = el.num; Object.keys(el).forEach(function (k) { function tryFindIndexAndSetNames(aa, i) { if (aa.title === k) { result[i].names[num] = el[k]; return true; } } if (k !== 'num' && !result.some(tryFindIndexAndSetNames)) { var o = {}; o[num] = el[k]; result.push({ title: k, names: o }); } }); }); document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>'); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM