按键/值创建数组内的对象数组

时间:2014-11-10 18:05:47

标签: javascript arrays sorting underscore.js

我一直在努力完成这项任务,但我似乎无法找到“正确的方法”去做,昨天我在这里要求修复我用纯javascript制作的代码,我得到了这个答案在我的旧question [已编辑]上使用下划线;

_.chain(arr)
  .groupBy(function(a) {return a.idBox; })
  .toArray()
  .map(function(es, i) { 
    return (es[0].idBox) ? {id: i, group: es[0].idBox, date: es[0].date , entries: es} : _.extend({id: i}, es[0]); 
  })
  .value()

不幸的是,它与我的情况无法正常工作,我遇到的第一个问题是它不维护原始排序(按日期,日期是从mysql已经排序的desc中检索的),其次是似乎如果有多个idBox的对象:null,第一个将生成它,但其他的(作为null)将不会使它成为value()。我正在创建一个新问题,因为它的上下文/问题本身非常不同,可能对其他人创建一个单独的问题更有帮助。

输入

[
  {
    id: 1,
    idbox: null,
    date: ""
  },
  {
    id: 4,
    idbox: 1,
    date: ""
  },
  {
    id: 3,
    idbox: 1,
    date: ""
  },
  {
    id: 2,
    idbox: null,
    date: ""
  },
  {
    id: 0,
    idbox: 1,
    date: ""
  },
  {
    id: 5,
    idbox: 2,
    date: ""
  }
]

预期产出;

[
  {
    id: 1,
    idbox: null,
    date: ""
  },
  {
    box: 1,
    objects: [ [Object], [Object], [Object] ]
  },
  {
    id: 2,
    idbox: null,
    date: ""
  },
  {
    box: 2,
    objects: [ [Object] ]
  }
]

实际输出;

[
  {
    box: 1,
    date: "",
    objects: [ [Object], [Object], [Object] ]
  },
  {
    box: 2,
    date: "",
    objects: [ [Object] ]
  },
  {
    id: 1,
    idbox: null,
    date: ""
  }
]

1 个答案:

答案 0 :(得分:0)

foldreduce是您的朋友。

arr = your_original_array

_.reduce(arr, function(memo, a) { 
  if (a.idbox == null) {
    memo.push(a);
  } else {
    b = _.find(memo, function(c) { return c.box == a.idbox });
    if (!b) {
      b = {box: a.idbox, objects: []};
      memo.push(b)
    }
    b.objects.push(a)
  }
  return memo
}, []);

您可以加快速度(如果原始数组中有数千条记录):

_.reduce(arr, function(memo, a) { 
  if (a.idbox == null) {
    memo.result.push(a);
  } else {
    b = memo.dict[a.idbox]
    if (!b) {
      b = { box: a.idbox, objects: [] };
      memo.result.push(b);
      memo.dict[a.idbox] = b;
    }
    b.objects.push(a);
  }
  return memo;
}, {dict: {}, result: []}).result;

reduce函数对数组中的每个元素进行操作。

reduce函数有两个参数:

  • 一个函数,它接受最后生成的结果(Underscore.js调用此memo)和当前元素。它以某种方式(检查函数体)将当前元素和最后一个结果组合成一个新结果。并且新结果将再次作为memo传递给该函数,并使用下一个项目,依此类推......

  • 备忘录的初始值

由于reduce逐个元素地遍历数组,因此该代码保留了顺序而无需引入排序键。