我使用node-linq并尝试理解GroupBy,但文档很少
例如我有这些数据:
{ “日期”: “2013年6月26日”, “名称”: “A”, “号码”:1}
{ “日期”: “2013年6月26日”, “名称”: “A”, “号码”:5}
{ “日期”: “2013年6月27日”, “名称”: “B”, “号码”:4}
{ “日期”: “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()
有人提出任何建议或只是关于GroupBy的一些例子吗?感谢
答案 0 :(得分:3)
您的代码中存在一些错误:
例如,而不是:
.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未实现异步链接,如ALINQ.coffee顶部的注释中所述(#TODO:GroupBy,ContainsAll)
6之前的ECMAScript没有大箭头=>样式lambda表示法,所以你必须使用map和reduce的某些组合才能达到我所知的相同功能,这可能意味着使用该功能增强node-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 } ]
为了修复和部分,请使用map和reduce。例如,您可以查看lambda-js:https://github.com/dfellis/lambda-js
答案 1 :(得分:2)
虽然您可以在github上的README中看到.GroupBy
,但在执行.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
我觉得好多了。