1

我使用 node-linq 并尝试了解 GroupBy,但文档很少

例如我有这个数据:

{“日期”:“2013/06/26”,“姓名”:“A”,“号码”:1}

{“日期”:“2013/06/26”,“姓名”:“A”,“号码”:5}

{“日期”:“2013/06/27”,“姓名”:“B”,“号码”:4}

{“日期”:“2013/06/27”,“姓名”:“A”,“号码”:4}

我想写这样的查询,但使用 LINQ for node js

SELECT date, name, SUM(number)
FROM data
GROUPBY date, name

我尝试此代码,但出现错误

var o = new LINQ(data)
        .Select(function(name,d) {return name.statement,d.date;})
        .SUM((function(x) {return x.number;)
        .GroupBy(function(name,d) {return name.statement,d.date;}
    .ToArray()
                

有人有任何建议或只是一些关于 GroupBy 的例子吗?谢谢

4

2 回答 2

3

您的代码中有一些错误:

  • 回调函数只接受一个参数,而不是两个
  • 在 Node(和 Javascript)中,如果您想返回多个项目,请将它们放在一个对象或数组中(例如用 {} 包装)
  • 在某些情况下,您的大括号和括号不匹配。

例如,而不是:

.Select(function(name,d) {return name.statement,d.date;})

你应该写:

.Select(function(item) { return { name: item.name, date: item.date } } )

而不是:

.GroupBy(function(name,d) {return name.statement,d.date;}

你应该写:

.GroupBy(function(item) { return { name: item.name, date: item.date } } )

但是,如 ALINQ.coffee 顶部的注释中提到的,对于异步链接,GroupBy 未实现(# TODO: GroupBy, ContainsAll)

并且 6 之前的 ECMAScript 没有大箭头 => 样式 lambda 表示法,因此据我所知,您必须使用 map 和 reduce 的一些组合才能实现相同的功能,这可能意味着增强节点-linq 具有该功能的库。

您现在可以使用 node-linq 最接近的可能是这样的:

var statement = [{"date":"2013/06/26","name":"A","number":1},
{"date":"2013/06/26","name":"A","number":5},
{"date":"2013/06/27","name":"B","number":4},
{"date":"2013/06/27","name":"A","number":4}]

var o = new LINQ(statement)
        .Select(function(item) {
               return {
                   date: item.date,
                   name: item.name, 
                   sum: new LINQ(statement).Sum(function(item){return item.number;})
               };
        })
        .OrderBy(function(item) {
               return [item.name, item.date];
         })
        .ToArray();

console.log(o);

这使:

[ { date: '2013/06/26', name: 'A', sum: 14 },
  { date: '2013/06/26', name: 'A', sum: 14 },
  { date: '2013/06/27', name: 'A', sum: 14 },
  { date: '2013/06/27', name: 'B', sum: 14 } ]

为了修复 sum 部分,请使用 map 和 reduce。例如,您可以查看 lambda-js:https ://github.com/dfellis/lambda-js

于 2013-06-27T15:51:44.863 回答
3

虽然您可以看到.GroupBygithub 上的 README 中有,.GroupBy但当您这样做时没有npm install node-linq. 所以你必须安装模块

npm install https://github.com/wearefractal/node-linq/tarball/master

这是您的数据:

var LINQ = require('node-linq').LINQ;

var data = [ { date: '2013/06/26', name: 'A', number: 1 },
             { date: '2013/06/26', name: 'A', number: 5 },
             { date: '2013/06/27', name: 'B', number: 4 },
             { date: '2013/06/27', name: 'A', number: 4 } ];

首先,您要将它们分组。不幸的是,您不能按哈希分组,因此您必须使用代理键:

var o = new LINQ(data).GroupBy(function(row) { return row.date + '~' + row.name; });
console.log(o);

这是输出:

{ '2013/06/26~A':
   [ { date: '2013/06/26', name: 'A', number: 1 },
     { date: '2013/06/26', name: 'A', number: 5 } ],
  '2013/06/27~B': [ { date: '2013/06/27', name: 'B', number: 4 } ],
  '2013/06/27~A': [ { date: '2013/06/27', name: 'A', number: 4 } ] }

接下来,您想对数字求和,但您不能。

console.log(o.__proto__); // {}

也许你需要把它包起来LINQ

new LINQ(o); // InvalidCastException: Data not Array

没有。

让我们通过丢失键将对象转换为数组。JavaScript 中没有Object.values(),所以我们必须这样做:

o = new LINQ(Object.keys(o).map(function(key) { return o[key] }));

现在我们终于可以对所有数字求和了:

o = o.Select(function(rows) { return { date: rows[0].date, name: rows[0].name, sum: new LINQ(rows).Sum(function(row) { return row.number; }) } }).ToArray();
console.log(o);

这是结果:

[ { date: '2013/06/26', name: 'A', sum: 6 },
  { date: '2013/06/27', name: 'B', sum: 4 },
  { date: '2013/06/27', name: 'A', sum: 4 } ]

不是很漂亮。

下划线

npm install underscore

以下是使用underscore库对数据进行分组的方法。

var _ = require('underscore')._;

var data = [ { date: '2013/06/26', name: 'A', number: 1 },
             { date: '2013/06/26', name: 'A', number: 5 },
             { date: '2013/06/27', name: 'B', number: 4 },
             { date: '2013/06/27', name: 'A', number: 4 } ];

var grouper = function(row) { return row.date + '~' + row.name; };
var summer = function(rows) { return rows.reduce(function(sum, row) { return sum + row.number; }, 0); };

var o  = _.chain(data)
          .groupBy(grouper)
          .map(function(rows) { return { date: rows[0].date, name: rows[0].name, sum: summer(rows) }; })
          .value();

console.log(o); // same result

好多了,我想。

于 2013-06-27T15:57:55.793 回答