【问题标题】:Iterating through an array and sum a value based on a condition in lo-dash遍历数组并根据 lo-dash 中的条件对值求和
【发布时间】:2014-11-05 15:26:56
【问题描述】:

我有一个已简化的数据集:

var data = [{
    size: 400
}, {
    size: 500
}, {
    size: 800
}, {
    size: 400
}, {
    size: 400
} {
    size: 300
}, {
    size: 300
}, {
    size: 800
}];
var windowWidth = 800;

使用 lo-dash 我将如何根据 windowWidth 的大小创建一个新数组。 优选的最终数据集将如下所示

var newArray = [{
            group: [0],
            size: 400
        }, {
            group: [1],
            size: 500
        }, {
            group: [2],
            size: 800
        }, {
            group: [3, 4],
            size: 800
        }, {
            group: [5,6],
            size: 600
        }, {

            group: [7],
            size: 800,
        }

关键字group指的是data[n]中满足小于windowwidth条件的索引。 键size 指的是组的累积大小。

注意:data[n] 只是计数,永远不会重复返回数据[0]。

data[n] 是否适合放在窗口内? 是的?推送到群组;去data[n +1 ].size;检查表达式

不是吗?创建新组();转到数据[n +1].size;检查表达式

【问题讨论】:

  • “基于 windowWidth 可以容纳多少尺寸”?什么?究竟应该如何从源头计算结果?
  • if(tempAccumlatedSize
  • stackoverflow.com/questions/26751236/… 继承了在 forloops 中完成的相同问题
  • 我仍然不明白输入数组会发生什么。请在该结果中添加对 groupsize 含义的确切解释。
  • 您是否仅按数组顺序组合项目?换句话说,您不会将索引 0 处的项目(大小:400)与索引 3 处的项目(大小:400)匹配,因为它们可能是

标签: javascript arrays loops underscore.js lodash


【解决方案1】:
var sum = _.chain(data).pluck('size').reduce(function(result, val, i) {    
    if (_.isEmpty(result) || val + _.last(result).size > windowWidth)
        result.push({ size: val, groups: [i] });
    else
    {
        var last = _.last(result);
        last.size += val;
        last.groups = last.groups || [];
        last.groups.push(i);
    }
    return result;
}, []).value();

http://jsfiddle.net/219g9hqm/

【讨论】:

    【解决方案2】:

    看来我知道你需要什么了:

    var data = [{size: 400}, {size: 500}, {size: 800}, {size: 400}, {size: 400}, {size: 300}, {size: 300}, {size: 800}],
        newArray = [],
        prevSize = 0,
        lastIndex,
        windowWidth = 800;
    for(var i = 0; i < data.length; i++){
        lastIndex = newArray.length - 1;
        if(prevSize == data[i].size && (newArray[lastIndex].size + data[i].size < windowWidth)){
            newArray[lastIndex].group.push(i);
            newArray[lastIndex].size += data[i].size;
        }else{
            prevSize = data[i].size;
            newArray.push({group:[i], size: data[i].size});
        }
    }
    
    console.log(newArray);
    alert(JSON.stringify(newArray));

    【讨论】:

    • 除非它没有使用 lo-dash :)
    • Cerbrus 以前的大小将始终是一个静态数字,例如 800,您可以在考虑到这一点的情况下重写它吗?
    • 你的权利,我认为这是更好的选择。我认为使用 lo dash 会更容易,但这相当易读
    • @Cerbrus 如果前 3 个索引大小是 200 怎么办?那会产生 {group:[0,1,2],size:600 } 吗?在我的手机上只是不想失去你
    • @MatthewHarwood:是的,会的。
    【解决方案3】:

    不确定这是否是最好的方法,但它只使用 lodash 函数:

    var indexed = _.map(data, function (e, i) {
      e['index'] = i;
      return e
    });
    var grouped = _.groupBy(indexed, function (e) {
      return e.size
    });
    var newArray = _.map(grouped, function (e, key) {
      return {'size': key, 'group': _.pluck(e, 'index')}
    });
    

    版本 2

    使用_.reduce 进行分组和_.map 将分组对象转换为对象列表的效率较低的版本。过滤掉所有大于windowWidth的大小。

    var windowWidth = 400;
    var grouped = _.reduce(data, function (result, e, i) {
      if (e.size <= windowWidth) {
        var group = result[e.size];
        if (!group) {
          group = result[e.size] = [];
        }
        group.push(i)
      }
      return result;
    }, {});
    var newArray = _.map(grouped, function (e, key) {
      return {'size': key, 'group': e}
    });
    

    Demo

    【讨论】:

    • @Cerbrus 是的,我最多知道 4 次。仅使用 lodash 函数只是一种尝试/练习。不要假装是最佳的:)。
    猜你喜欢
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    相关资源
    最近更新 更多