Node Groupby dan LINQ js

Saya menggunakan node-linq dan mencoba memahami GroupBy, tetapi dokumentasinya sangat sedikit

misalnya saya punya data ini:

{tanggal:26/06/2013,nama:A,nomor:1}

{tanggal:26/06/2013,nama:A,nomor:5}

{tanggal:27/06/2013,nama:B,nomor:4}

{tanggal:27/06/2013,nama:A,nomor:4}

dan saya ingin menulis kueri seperti ini tetapi dengan LINQ untuk node js

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

Saya mencoba kode ini tetapi saya mendapatkan Kesalahan

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()
                

adakah yang punya saran atau hanya beberapa contoh tentang GroupBy? Terima kasih


person dardar.moh    schedule 27.06.2013    source sumber
comment
Jangan anggap LINQ sebagai SQL; itu benar-benar tidak membantu.   -  person Callum Rogers    schedule 27.06.2013


Jawaban (2)


Meskipun Anda dapat melihat bahwa ada .GroupBy di README di github, tidak ada .GroupBy saat Anda melakukan npm install node-linq. Jadi, Anda harus menginstal modul dengan

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

Ini adalah data Anda:

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 } ];

Pertama, Anda ingin mengelompokkannya. Sayangnya, Anda tidak dapat mengelompokkan berdasarkan hash sehingga Anda harus menggunakan kunci pengganti:

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

Ini adalah hasilnya:

{ '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 } ] }

Selanjutnya, Anda ingin menjumlahkan angka-angkanya, tetapi tidak bisa.

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

Mungkin Anda perlu membungkusnya dengan LINQ?

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

Tidak.

Mari kita ubah objek menjadi array dengan kehilangan kuncinya. Tidak ada Object.values() di JavaScript, jadi kita harus melakukannya dengan cara ini:

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

Sekarang kita akhirnya dapat menjumlahkan semua angka:

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);

Inilah hasilnya:

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

Tidak terlalu cantik.

Menggarisbawahi

npm install underscore

Berikut cara mengelompokkan data Anda menggunakan pustaka 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

Jauh lebih bagus, menurutku.

person mak    schedule 27.06.2013
comment
Saya mengerti terima kasih banyak atas bantuan Anda, kodenya berfungsi 100% - person dardar.moh; 27.06.2013

Ada beberapa kesalahan dalam kode Anda di sana:

  • Fungsi panggilan balik hanya menerima satu argumen, bukan dua
  • Di Node (dan Javascript) jika Anda ingin mengembalikan beberapa item, masukkan item tersebut ke dalam objek atau array (bungkus dengan {} misalnya)
  • Dalam beberapa kasus, kurung kurawal dan tanda kurung tidak cocok.

Misalnya, alih-alih:

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

Anda harus menulis:

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

dan bukannya:

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

Anda harus menulis:

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

Namun, GroupBy tidak diterapkan untuk tautan asinkron seperti yang disebutkan dalam catatan di bagian atas ALINQ.coffee (# TODO: GroupBy, BerisiSemua)

Dan ECMAScript sebelum 6 tidak memiliki notasi lambda gaya panah => besar, jadi Anda harus menggunakan beberapa kombinasi map dan pengurangan untuk mencapai fungsi yang sama sejauh yang saya tahu, yang mungkin berarti meningkatkan node -linq perpustakaan dengan kemampuan itu.

Hal terdekat yang bisa Anda dapatkan dengan menggunakan node-linq saat ini mungkin adalah seperti ini:

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);

yang memberikan:

[ { 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 } ]

Untuk memperbaiki bagian penjumlahan, gunakan map dan kurangi. Misalnya, Anda dapat melihat lambda-js: https://github.com/dfellis/lambda-js

person Matt Mullens    schedule 27.06.2013