2017-04-26 120 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'}] 

我希望能夠做的是組數據使得例如用於ID1上的數據12年12月1日的總和col2列的是什麼。或者,對於id2,2012年12月12日至2012年1月13日期間col2的值有什麼區別。

相當新的(1周)JS,所以任何意見,將不勝感激。

+0

我建議你看看一個名爲lodash(下劃線)的庫。它幫助與js的數組相關的功能 – user5328504

+0

可能重複[什麼是最有效的方法來groupby一個JavaScript數組的對象?](http://stackoverflow.com/questions/14446511/what-is-the-most-有效的方法到對象上的一個javascript對象) –

回答

1

對於分組,我使用Array過濾方法。如果您希望在已過濾的數組中包含一個數組元素,它將接收一個應該返回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'; 
          }); 

對於一個組內總結一列,可以使用Array減少方法。它將第一個參數作爲一個「減少」函數,將數組元素減少爲單個值。它以可選的第二個參數作爲起始值。還原函數必須有兩個參數。在第一次迭代中,第一個參數是指定的起始值,在後續迭代中,它是前一次迭代中函數的返回值。還原函數的第二個參數是數組的一個元素。所以總結您的分組數據的第二列,你會怎麼做:

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

看看其他陣列的方法,你會發現其他人可能是你這取決於你想要做什麼有用的。

+0

謝謝 - 這正如我所希望的那樣工作,將需要使其更通用,但很確定這不會是一個問題。 我有一個關於reduce函數的問題,0的目的是什麼,因爲包括它給了我正確的總結,就好像我不包含它一樣,我得到了一個打印出來的所有值,如:123100-10。 我閱讀文檔,它說它設置初始值,但這似乎並不能解釋我的結果。 再次感謝您 – GoodCat

+0

0是減少結果的初始值。因此,在上面的示例中,在reduce的第一次迭代中,sumSoFar爲0(指定爲第二個參數以減少),並將行分組爲[0]。在該迭代中,該函數返回0 + 123 = 123,該值在第二次迭代中成爲sumSoFar的值,其中row = grouped [1]。在該迭代中,該函數返回123 + 100 = 223,這是結果。如果你省略零,那麼在reduce的第一次迭代中,sumSoFar被分組[0]並且行被分組[1] ... – cjg

+0

...當我刪除零並按原樣運行函數時,我得到' [對象對象] 100'。這是因爲函數返回了sumSoFar + parseInt(row.col2)= groupped [0] + parseInt(grouped [1] .col2]。grouped [0]是一個對象,但它被轉換爲一個字符串('[object Object ]')和+被視爲字符串連接運算符,因此grouped [1] .col2被轉換回一個字符串並連接到'[object Object]'如果你改變函數返回sumSoFar.col2 + parseInt(row .col2),那麼我希望你得到的結果,出於類似的原因... – cjg

1

我創建了一個函數,它的參數是一個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

相關問題