【问题标题】:Filtering elements based on accumulated sum of a field根据字段的累积和过滤元素
【发布时间】:2016-08-12 10:23:40
【问题描述】:

考虑这样的数据对象

var data = [
    {name: 'abc', dis: 0},
    {name: 'bcd', dis: 30},
    {name: 'cde', dis: 70},
    {name: 'def', dis: 22},
    {name: 'efg', dis: 40},
    {name: 'fgh', dis: 29},
    {name: 'ghi', dis: 41},
    {name: 'hij', dis: 33}
];

我只想在累积距离大于或等于100时过滤掉对象。所以需要的输出是

var finalData = [
    {name: 'abc', dis: 0},  //start point
    {name: 'cde', dis: 100}, // 0 + 30 + 70
    {name: 'ghi', dis: 132}, //22 + 40 + 29 + 41
    {name: 'hij', dis: 33}  // 33 as points ended
];

当然,我可以通过 for-loop 轻松完成并像这样推送

var finalData = [];
var sum = 0;
for(var i=0;i<data.length;i++) {
    sum += data[i].dis;
    if(i == 0 || sum >= 100) {
        finalData.push({name: data[i].name, dis: sum});
        sum = 0;
    }

}

但想以 Rxjs 风格学习它。

【问题讨论】:

  • IMO,for 循环将是最简洁的编码方式。
  • 代码相同,但使用reduce更容易推理。

标签: javascript functional-programming rxjs5


【解决方案1】:

我不确定特定的 RxJS 功能在这种情况下是否有帮助。你是说函数式编程吗?

您可以将.reduce() 方法与累加器一起使用,并对第一个和最后一个元素进行额外测试。

据我所知,您的原始代码仅缺少对最后一个元素的测试。

var data = [
  {name: 'abc', dis: 0},
  {name: 'bcd', dis: 30},
  {name: 'cde', dis: 70},
  {name: 'def', dis: 22},
  {name: 'efg', dis: 40},
  {name: 'fgh', dis: 29},
  {name: 'ghi', dis: 41},
  {name: 'hij', dis: 33}
];

var sum = 0;

var finalData = data.reduce(function(prv, cur, i) {
  if((sum += cur.dis) >= 100 || !i || i == data.length - 1) {
    cur.dis = sum;
    sum = 0;
    prv.push(cur);
  }
  return prv;
}, []);

console.log(finalData);

如果您想避免使用在.reduce() 方法范围之外定义的变量,您可以使用可选的thisArg 参数或对象而不是简单数组作为初始值。

我更喜欢第二个选项,它允许从头显式初始化累加器:

var data = [
  {name: 'abc', dis: 0},
  {name: 'bcd', dis: 30},
  {name: 'cde', dis: 70},
  {name: 'def', dis: 22},
  {name: 'efg', dis: 40},
  {name: 'fgh', dis: 29},
  {name: 'ghi', dis: 41},
  {name: 'hij', dis: 33}
];

var finalData = data.reduce(function(prv, cur, i) {
  if((prv.sum += cur.dis) >= 100 || !i || i == data.length - 1) {
    cur.dis = prv.sum;
    prv.sum = 0;
    prv.res.push(cur);
  }
  return prv;
}, {sum: 0, res: []}).res;

console.log(finalData);

【讨论】:

  • 无论如何要避免对全局变量 sum 的依赖?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-18
  • 1970-01-01
  • 2015-11-27
  • 2020-02-13
  • 1970-01-01
相关资源
最近更新 更多