使用array.map或array.filter

时间:2015-12-21 20:55:48

标签: javascript arrays

我的端点提供如下数据:

[{
    "category": "square",
    "color": "blue",
    "groups": [{
        "side": "left",
        "group_id": "212"
      }, {
        "side": "left",
        "group_id": "213"
      }]
  },{
    "category": "square",
    "color": "red",
    "groups": [{
        "side": "left",
        "group_id": "212"
      },{
        "side": "right",
        "group_id": "215"
      }]
}]

我想要做的是按照categorycolor的{​​{1}}和side来计算用户数量。所以我最终会得到一个像这样的对象数组:

group_id

我一次只知道一个[{ "group_id": "212", "side": "left", "category": "square", "color": "blue", "total": 1 },{ "group_id": "212", "side": "left", "category": "square", "color": "red", "total": 1 },{ // etc [truncated] }] (即“212”)。每个条目的组对象可以有所不同(订单数量),因此group_id不一定是所讨论的user.groups[0]。但是我不会拥有group_id的总数,无论如何,循环似乎过多。

在伪代码中,我认为逻辑会像:

user.groups.group_id

Array.filter似乎不适合这个用例(至少可以通过我能找到的例子),而array.map似乎用于减少事情,而不是匹配事物(不确定)。是否有一种有效的方法来处理这些数据以通过属性和子属性设置组,因此我可以获得每个数据的总数?

提前感谢!

3 个答案:

答案 0 :(得分:1)

我可能会用reduce来解决这个问题。我假设你正在追踪特定方面的数据和group_id。

var side = 'left';

var group_id = '212';


data.reduce(function(accumulator, currentObject) {

  var resultObj = {
    count: 0, 
    side: side, 
    group_id: group_id, 
    color: currentObject.color, 
    category: currentObject.category
  };

  currentObject.groups.forEach(function(object) {
    if (object.group_id === group_id && object.side === side) {
      resultObj.count++
    }
  });

  accumulator.push(resultObj);

  return accumulator;

}, []);

答案 1 :(得分:1)

因为你提到"高效"然后值得注意的是,在Javascript中使用for循环几乎总是更高效,然后使用.map().reduce().filter()或其他使用回调的方法迭代。

以下是一个例子:

var result = {}
for (var i = 0, len = data.length; i < len; i++) {
  var item = data[i]
  for (var i2 = 0, len = item.groups.length; i2 < len; i2++) {
    var group = item.groups[i2]

    var key = [group.group_id, group.side, item.category, item.color].join()

    var x = result[key] || {
        group_id: group.group_id,
        side: group.side,
        category: item.category,
        color: item.color,
        total: 0
      }
      ++x.total
    result[key] = x
  }
}

// convert result to an array
var results = []
for (var p in result) {
  if (result.hasOwnProperty(p)) {
    results.push(result[p])
  }
}

return results

答案 2 :(得分:1)

对于数组的每个元素,您希望将其类别和颜色信息添加到其组的每个元素,然后将所有组的所有元素收集在一个大数组中。因此,您希望映射元素,以及要在其组上映射的每个元素,然后最终要连接所有组。像这样:

var data = [{category: "square",
             color: "blue",
             groups: [{side: "left", group_id: "212"},
                      {side: "left", group_id: "213"}]},
            {category: "square",
             color: "red",
             groups: [{side: "left", group_id: "212"},
                      {side: "right", group_id: "215"}]}]

var output = [].concat.apply([], data.map(
    function(obj){
        return obj.groups.map(
            function(o){
                o.category = obj.category;
                o.color = obj.color;
                return o;
            });
    }));