JSON - 对象数组到数组对象

时间:2015-10-23 16:14:22

标签: javascript arrays json functional-programming

我有一系列JSON条目:

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

我试图尽可能轻松地将这个对象数组转换为两个对象 - 一个标题为name_A,第二个标题为name_B。对象必须包含标题和匹配的数字对的数组:

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

首先,我尝试通过减少对象数组两次创建两个对象,一次是name_A,第二次是name_B,后来将所有内容粘合在一起:

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

但即使这样也失败了。如果我使用空数组初始化reduce,为什么没有用于备忘录的推送方法?

第二个问题,我是在正确的轨道上还是有更好的方法来实现这个目标?

3 个答案:

答案 0 :(得分:1)

您的代码存在的问题是{ curr.num, curr.name_A }不是有效对象,它缺少属性名称。我在下面的代码中添加了属性numname

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 }
];

此外,如果您想在循环数组的结果中创建数组,则应使用.map而不是.reduce

答案 1 :(得分:1)

内联评论,对期望做了一些小修改。

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>

答案 2 :(得分:0)

假设只修复了属性num。所有其他属性都被视为数据,例如name_Aname_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>');