在下划线groupBy之后加入或合并json对象

时间:2012-12-10 19:08:15

标签: javascript json underscore.js

我在当前项目中使用了underscore.js,它有一个很好的_.groupBy方法。

这将我的数组分组为这种格式。

var obj1 ={
  '0':[{ ... json object...},{ ... json object...},{ ... json object...}],
  '1':[{ ... json object...},{ ... json object...},{ ... json object...}],
  '2':[{ ... json object...},{ ... json object...},{ ... json object...}]
}

var obj2 = {
  '0':[{ ... another json object...},{ ...another json object...}],
  '1':[{ ... another json object...},{ ...another json object...}],
  '2':[{ ... another json object...},{ ... another json object...}]
}

现在我想加入/合并/扩展它们......但是_.extend不能像我期望的那样工作。

我的预期结果是

{'0':[{ ... json object...},{ ... json object...},{ ... json object...},{ ... another json object...},{ ...another json object...}],
'1':[{ ... json object...},{ ... json object...},{ ... json object...},{ ... another json object...},{ ...another json object...}],
 '2':[{ ... json object...},{ ... json object...},{ ... json object...},{ ... another json object...},{ ... another json object...}]}

基本上我需要基于obj1obj2的json键扩展数组,即使内部json对象不同。

基本上需要像json对象的sql join操作......

所以任何帮助都会很棒......

2 个答案:

答案 0 :(得分:3)

好吧,因为没有出现下划线.js特定的答案,这里是一般的JavaScript:

要将obj2合并到obj1,请遍历obj2的条目,并将这些数组附加到obj1上的等效数组中,如下所示:

var key, a1, a2;
for (key in obj2) {
  if (obj2.hasOwnProperty(key)) {
    a2 = obj2[key];
    a1 = obj1[key];
    if (a1) {
      a1.push.apply(a1, a2); // Tricky, see below
    }
    else {
      obj1[key] = a2;
    }
  }
}

obj2合并到obj1,修改obj1的数组。如果obj2在相应的插槽中没有一个数组,它会重复使用obj1的数组。

Live Example | Source

关于那个“棘手”的一点:

a1.push.apply(a1, a2);

这样做追加a2a1末尾的元素。 Details on my blog,但基本上,Array#push会将元素添加到数组的末尾,就像您指定为参数一样多(例如,a.push(1, 2, 3)推送123到数组上),Function#apply调用函数指定要用作this(第一个参数)的内容和传递给它的参数,作为数组(第二个)参数)。

答案 1 :(得分:1)

我需要做类似的事情。加入两个对象,但确保groupby字段具有相同的名称san。我需要从score附加some_scores。需要_.each来创建外连接。 Map使用您需要的名称/值创建最终对象:

   var x = _.chain(moves)
            .union(some_scores)    
            .groupBy('san')
            .each(function(o){ o.push({score:''}); })
            .map(function(o){return {san:o[0].san, to:o[0].to, score:o[1].score  }; })
            .value();