javascript - 从表数据中删除列的最佳方法是什么?

标签 javascript underscore.js

考虑以下数据:

[
  { time: '5:00', name: 'bran', fruit: 'pear', numEaten: 3},
  { time: '5:00', name: 'rickon', fruit: 'apple', numEaten: 2},
  { time: '6:00', name: 'bran', fruit: 'apple', numEaten: 5},
  { time: '6:00', name: 'rickon', fruit: 'grape', numEaten: 1},
  { time: '6:00', name: 'bran', fruit: 'pear', numEaten: 2},
  { time: '6:00', name: 'eddard', fruit: 'pear', numEaten: 2},
  { time: '7:00', name: 'rickon', fruit: 'apple', numEaten: 7}
]

我想要做的是删除一列,并添加具有匹配列的所有行的“numEaten”。想象一下:您实际上并不关心什么时候吃水果,您只想知道谁吃了多少。所以输出表看起来像:

[
  {name: 'bran', fruit: 'pear', numEaten: 5},
  {name: 'bran', fruit: 'apple', numEaten: 2},
  {name: 'rickon', fruit: 'apple', numEaten: 9},
  {name: 'rickon', fruit: 'grape', numEaten: 1},
  {name: 'eddard', fruit: 'pear', numEaten: 2},
]

我一直在查看 underscore 中的各种 javascript 数组原型(prototype)函数和扩展,但我看不到一种特别优雅的方法来执行此操作。我想要一个带有原型(prototype)的函数:

function aggregate(data, column, aggregateColumn) // aggregate(data, 'time', 'numEaten')

将执行此操作。从概念上讲,我正在考虑为不是 columnaggregateColumn 的每个列运行 _.groupBy(),但是让它工作似乎有点老套。有没有更好的办法?

编辑

似乎没有针对此解决方案的单行解决方案:在合并以下解决方案的反馈后,发布我的想法。请注意,与原始问题不同,这需要列保留,而不是删除,并且适用于任何模式。

  var aggregate = function(data, aggregateColumn, keepColumns) {
    keepColumns = keepColumns || [];
    if(!Array.isArray(keepColumns)) {
      keepColumns = [ keepColumns ];
    }

    var removeColumns = _.difference(_.keys(data[0]), keepColumns.concat(aggregateColumn));
    var grouped = _.groupBy(data, function(d) {
      return _.reduce(keepColumns, function(o, col) {
        return o + d[col] + '-';
      }, '');      
    });

    return _.map(grouped, function(mapData) {
      var reduced = _.reduce(keepColumns, function(o, col) {
          o[col] = mapData[0][col];
          return o;
        }, {}
      );

      reduced[aggregateColumn] = _.reduce(mapData, function(o, aggrData) {
          return o + aggrData[aggregateColumn];
        }, 0
      );

      return reduced;
    });
  }

最佳答案

下面是用下划线实现的一种方法

让我们定义初始数据,如

var data = [
  { time: '5:00', name: 'bran', fruit: 'pear', numEaten: 3},
  { time: '5:00', name: 'rickon', fruit: 'apple', numEaten: 2},
  { time: '6:00', name: 'bran', fruit: 'apple', numEaten: 5},
  { time: '6:00', name: 'rickon', fruit: 'grape', numEaten: 1},
  { time: '6:00', name: 'bran', fruit: 'pear', numEaten: 2},
  { time: '6:00', name: 'eddard', fruit: 'pear', numEaten: 2},
  { time: '7:00', name: 'rickon', fruit: 'apple', numEaten: 7}
]

然后,根据 namefruit 加入他们来创建组。

var groups = _.groupBy(data, function(value){
        return value.name+ '#' + value.fruit;
    });

稍后我们将在聚合时使用这个自定义的 sum 函数。

function sum(numbers) {
    return _.reduce(numbers, function(result, current) {
        return result + parseFloat(current);
    }, 0);
}

现在,通过提取 numEaten 并取其总和

映射
var out = _.map(groups, function(group){
        return {
            name: group[0].name,
            fruit: group[0].fruit,
            numEaten: sum(_.pluck(group, 'numEaten'))
        }
    });

最后我们得到了这样的输出——

out
[
  {name: 'bran', fruit: 'pear', numEaten: 5},
  {name: 'bran', fruit: 'apple', numEaten: 5},
  {name: 'rickon', fruit: 'apple', numEaten: 9},
  {name: 'rickon', fruit: 'grape', numEaten: 1},
  {name: 'eddard', fruit: 'pear', numEaten: 2},
]

关于javascript - 从表数据中删除列的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29766047/

相关文章:

javascript - 415(不支持的媒体类型)与 REST 发布请求

javascript - 如何检测特定 div 何时不在 View 中

javascript - Javascript 中值列表的动态验证

javascript - 将文本转换为 Canvas 图像,保留格式

JavaScript/Underscore 获取对象中所有项目的最小最大值

javascript - 了解 BackboneJS

javascript - Date.getTime() 为相同的时间戳给出两个不同的值

javascript - 通过比较获取最大 Underscore.js

JavaScript 绑定(bind)语法

javascript - 主干集合 - 如何用其他集合过滤集合?