Groupby和LINQ节点js
我使用node-linq,并尝试了解GroupBy,但文档太less了
例如我有这样的数据:
{ “date”: “2013年6月26日”, “名称”: “A”, “号码”:1}
{ “date”: “2013年6月26日”, “名称”: “A”, “号码”:5}
{ “date”: “2013年6月27日”, “名称”: “B”, “号码”:4}
{ “date”: “2013年6月27日”, “名称”: “A”, “号码”:4}
我想写这样的查询,但与LINQ的节点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()
有人有任何build议或只是关于GroupBy一些例子? 谢谢
虽然你可以看到在github的README中有.GroupBy
,但是当你执行npm install node-linq
时候没有.GroupBy
。 所以你必须安装模块
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
更好,我想。
你的代码有一些错误:
- callback函数只接受一个参数,而不是两个
- 在节点(和Javascript)中,如果你想返回多个项目,把它们放在一个对象或数组中(例如,用{}换行)
- 括号和括号在less数情况下不匹配。
例如,而不是:
.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 } } )
但是,GroupBy未实现asynchronous链接,如ALINQ.coffee(#TODO:GroupBy,ContainsAll)顶部的注释中所述,
而且,在6之前的ECMAScript没有大的箭头=>样式的lambda表示法,所以你必须使用map和reduce的一些组合来实现相同的function,据我所知,这可能意味着增强节点具有该function的-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 } ]
为了修复和部分,使用地图和减less。 例如,你可以看看lambda-js: https : //github.com/dfellis/lambda-js