Groupby和LINQ节点js

时间:2013-06-27 14:50:44

标签: javascript linq node.js

我使用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的一些例子吗?感谢

2 个答案:

答案 0 :(得分: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 } } )

但是,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

我觉得好多了。