2017-08-02 155 views
0

我有一個包含以下對象的數組。遍歷一個對象數組並根據條件添加到其他數組

var notTotal = [{"Year":2012,"Value":800579}, 
       {"Year":2012,"Value":654090}, 
       {"Year":2012,"Value":758092}, 
       {"Year":2013,"Value":343928},...More objects.. ] 

我想要做的是遍歷這個對象數組,其中只有一年存在而不是多個,並且將當年的值加起來。用上面的例子..

var total = [{"Year":2012,"Value":2556689}, 
//Total of first three 2012 assuming there isnt anymore 2012 in the array 
      {"Year":2013,"Value":343928},...] 

我已經試過類似如下:

for(var i = 0; i < notTotal.length; i++) { 
    if (total.includes(notTotal[i].Year || notTotal[i])) { 
     //Add the value of the year in notTotal array to the same year in total array 
    } else { 
    total.push(notTotal[i]); //add year and value if it does not exist to the total array 
} 
} 

道歉,如果這是一個重複。這似乎是一個非常具體的問題。

謝謝!

+0

你所需要的最終結果('total')是一個數組?使用將字符映射到值的字典可以非常容易地實現(因爲鍵必須是唯一的)。 – AstroCB

+0

請參閱[這個答案](https://stackoverflow.com/questions/23521894/how-to-aggregate-objects-properties)。 –

+0

它需要是一個數組,然後將其插入到D3條形圖佈局中。 – Stu

回答

2

一個簡單的解決方案是創建一個對象,持有總量按年份。

var totalByYear = {}; 

然後,您可以使用循環的notTotal.forEach陣列或for循環,你已經證明,增加了有關今年totalByYear物體內部的價值在。

notTotal.forEach(function(ele) { totalByYear[ele.Year] += ele.Value }); 

這產生具有年份鍵和總值的對象,例如,使用例如:

{'2012': 2556689, '2013': 343928 /* other years */} 

所述期望的格式(對於D3)然後可以從totalByYear對象(以及由年總計印刷)內置:

var totals = []; 
for (year in totalByYear) { 
    console.log('Total for year ' + year + ' is ' + totalByYear[year]); 
    //Build the correctly formatted array 
    totals.push({ Year: year, Value: totalByYear[year]}); 
} 

//Prints: 
//Total for year 2012 is 2556689 
//etc.etc. 

totals陣列然後將具有所需格式。

+0

很棒的回答。然而,我需要保留[{「Year」:yyyy,「Value」:n} ...]的格式,然後使用它來放入D3.js佈局。 – Stu

+0

@sru您可以使用最後一行的psidoms最後一步... –

+0

我已經添加到答案的結尾,顯示如何保留'D3.js' –

0

,你可以建立一個哈希表:

var hash = {},total=[]; 
for(const {Year,Value} of notTotal){ 
    if(hash[Year]){ 
    hash[Year].Value+=Value; 
    }else{ 
    total.push(hash[Year]={Year,Value}); 
    } 
} 

In action

注:對象屬性通常不大寫...

+0

讚賞。我從D3.json函數加載這些數據,並且這些屬性已經大寫了。 – Stu

1

偉大的問題!要解釋您的if (total.includes(notTotal[i].Year || notTotal[i]))中發生的情況是,您正在通過total陣列查看一年中的數據,或者僅僅是現有的notTotal[i]。所以你的循環試圖找到一個值正好是2012或正好"Year":2012,"Value":2556689。 ERGO,如果你的total數組是這樣的:

[{"Year":2012, "Value": 12345}] 

你的循環將找不到它,即使沒有與2012爲一年的對象。至於如何解決這個問題,請看看前面的問題!

How to determine if Javascript array contains an object with an attribute that equals a given value?

希望幫助:)

+0

的格式,因爲年份始終是真的,或是無關緊要的...... –

+0

真的!非常感謝你指出:) –

0

你可以使用一個哈希表,並檢查今年不存在,然後生成一個新的結果集。然後更新總數。

var values = [{ Year: 2012, Value: 800579 }, { Year: 2012, Value: 654090 }, { Year: 2012, Value: 758092 }, { Year: 2013, Value: 343928 }], 
 
    hash = Object.create(null), 
 
    totals = []; 
 
    
 
values.forEach(function (o) { 
 
    hash[o.Year] || totals.push(hash[o.Year] = { Year: o.Year, Value: 0 }); 
 
    hash[o.Year].Value += o.Value; 
 
}); 
 

 
console.log(totals);

1

var notTotal = [{"Year":2012,"Value":800579}, 
 
       {"Year":2012,"Value":654090}, 
 
       {"Year":2012,"Value":758092}, 
 
       {"Year":2013,"Value":343928}] 
 
       
 
var totalObj = notTotal.reduce((sum, obj) => { 
 
    sum[obj.Year] = sum[obj.Year] + obj.Value || obj.Value; 
 
    return sum; 
 
}, {}); 
 

 
// convert total to the format you need; 
 
var total = Object.entries(totalObj).map(([Year, Value]) => ({Year, Value})) 
 

 
console.log(total);

+0

這相當於sebs的答案,不同之處在於他是第一個,並將努力付諸正確的解釋... –

1

多了一個解決方案:

function yearlyValueFilter(array){ 
    var yearlyValue = {} 
    array.forEach((obj) => { //litterate on the input 
    var year = obj.Year 
    var value = obj.Value 
    if((year in yearlyValue)){ //if the array with not duplicated years conatins the litteration year just plus that value 
     yearlyValue[year] += value 
    }else{  //if not conatins, it gets as a basic value 
     yearlyValue[year] = value 
    } 
    }) 
    return yearlyValue 
} 
+0

這既不是自我解釋,也不是可以理解的。 –