2017-04-26 8 views
1

私はCSVを持っています。配列にcsv経由でメモリにロードしています。これは、キーが列で、値が関連データであるデータの各行に対してキー値のペアを持つオブジェクトの配列を返しますその列。このように:特定の列に基づいてデータをJavascriptでグループ化する

[{col1: 'id1', col2: '123', col3: '12/01/12'}, 
{col1: 'id1', col2: '100', col3: '12/01/12'}, 
{col1: 'id2', col2: '-100', col3: '12/01/12'}, 
{col1: 'id2', col2: '123', col3: '13/01/12'}] 

私は何をできるようにしたいですグループのデータので、列col2の合計したものをデータ12/01/12上ID1ため例えば。または、id2の場合、col2の値の12/01/12と13/01/12の間の差はどうでしたか?

JSについてはかなり新しい(1週間で)ですので、これに関するアドバイスは大変ありがとうございます。

+0

lodash(アンダースコア)というライブラリを調べることをお勧めします。それはjsの配列に関連する機能を支援します – user5328504

+0

[オブジェクトのjavascript配列のgroupbyに最も効率的な方法は何ですか?](http://stackoverflow.com/questions/14446511/what-is-themost-効率的なメソッドからグループへのオブジェクトの配列による) –

答えて

1

、Iは、アレイフィルタ方式を使用したいです。フィルタされた配列に配列要素を含めるには、trueを返す関数が必要です。だから、COL1は「ID1」とCOL3である'12/01/12' であるため、行を取得するには、どうなる:

var data = [{col1: 'id1', col2: '123', col3: '12/01/12'}, 
      {col1: 'id1', col2: '100', col3: '12/01/12'}, 
      {col1: 'id2', col2: '-100', col3: '12/01/12'}, 
      {col1: 'id2', col2: '123', col3: '13/01/12'}]; 

var grouped = data.filter( function(row) { 
           return row.col3 == '12/01/12' && row.col1 == 'id1'; 
          }); 

グループ内の列を合計するためには、アレイは、メソッドを減らすことができます。最初の引数として配列の要素を単一の値に減らす "reduce"関数をとります。オプションの第2引数として開始値をとります。還元関数は2つの引数を取る必要があります。最初の反復では、最初の引数は指定された開始値であり、それ以降の反復では、前の反復での関数の戻り値です。 reduce関数の第2引数は配列の要素です。だからあなたのグループ化されたデータの2番目の列を合計する、あなたは何だろう:他の配列方法で

var sumOfGrouped = grouped.reduce(function(sumSoFar, row) { return sumSoFar + parseInt(row.col2) }, 0); 

見て、あなたはあなたが何をしたいかに応じて、ために有用である可能性が他の人を見つけるでしょう。

+0

ありがとうございます - これは私が望んでいたのとまったく同じように機能しました。より汎用的にする必要がありますが、これは問題ではないと確信しています。 reduce関数には1つの質問がありますが、0の目的は何ですか?それは私に正しい集計を与えます。私がそれを含まない場合、私はこのようなすべての値からプリントを取得します。123100-10。 ドキュメントを読みましたが、初期値を設定していますが、これは私の結果を説明していないようです。 ありがとうございました – GoodCat

+0

0は、削減結果の初期値です。したがって、上記の例では、reduceの最初の反復では、sumSoFarは0(reduceの第2引数として指定されます)であり、rowはグループ化されています[0]。その反復では、関数は0 + 123 = 123を返します。これは、2回目の繰り返しでsumSoFarの値になり、row = grouped [1]となります。その反復では、関数は123 + 100 = 223を返します。これは結果です。 0を省略すると、reduceの最初の反復で、sumSoFarはグループ化され[0]、行はグループ化されます[1] ... – cjg

+0

...ゼロを削除してそのまま関数を実行すると、 [オブジェクトオブジェクト] 100 '。これは、関数がsumSoFar + parseInt(row.col2)= grouped [0] + parseInt(grouped [1] .col2)を返すためです。 ] ')、+は文字列連結演算子として扱われます。grouped [1] .col2は文字列に変換され、' [object Object] 'に連結されます。あなたが得た結果は、同様の理由から期待しています... – cjg

1

私はパラメータwhoが列名を表すStringである関数を作成しました。この例では、私は"col1" - ID列を渡しています。

この関数は、空のオブジェクトを作成します。データ配列をループし、同じIDを持つオブジェクトがすでに格納されているかどうかをチェックします。そうでなければ、IDと同じ名前の新しいプロパティを作成して空の配列を割り当てます。

この空の配列には、同じIDを持つオブジェクトが含まれます。グループ化

var data = [ 
 
    {col1: 'id1', col2: '123', col3: '12/01/12'}, 
 
    {col1: 'id1', col2: '100', col3: '12/01/12'}, 
 
    {col1: 'id2', col2: '-100', col3: '12/01/12'}, 
 
    {col1: 'id2', col2: '123', col3: '13/01/12'} 
 
]; 
 

 
function sortData(columnName) { 
 
    var sortedData = {}; 
 

 
    for (var i = 0; i < data.length; i++) { 
 
     var object = data[i]; 
 

 
     if (Object.keys(sortedData).indexOf(object[columnName]) === -1) { 
 
      sortedData[object[columnName]] = []; 
 
     } 
 

 
     sortedData[object[columnName]].push(object); 
 
    } 
 
    
 
    return sortedData; 
 
} 
 

 
console.log(sortData("col1"));

+1

ありがとう - これは有用な出発点を提供し、私はおそらくcjgによって提供されたソリューションと一緒に使用しますが、彼は必要な正確な結果を提供しました – GoodCat

関連する問題