2015-06-05 2 views
1

У меня есть этот многомерный массив, и мне нужно, чтобы объединить поля, которые равны и просуммировать сумма значенийJavascript сумма многомерный массив

var data = [ 
     [ 
     {field: 123, sum: 100}, 
     {field: 345, sum: 98} 
     ],[ 
     {field: 123, sum: 12}, 
     {field: 345, sum: 20} 
     ] 
    ]; 

Так из этого массива мне нужен новый, как это.

var newArray = [ 
    {field: 123, sum: 112}, 
    {field: 345, sum: 118} 
]; 

и вот мой код.

var newArray = []; 
for(var i = 0; i < data.length; i++) { 
    for(var j = 0; j < data[i].length; j++) { 
    var matched = false; 
    for(var c = 0; c < newArray.length; c++) { 
     if(data[i][j].field == newArray[c].field) { 
     matched = true; 
     newArray[c].sum + data[i][j].sum; 
     } 
    } 
    console.log(data[i][j]); 
    if(!matched) { 
     newArray.push(data[i][j]); 
    } 
    } 
} 

, но я не получаю значения правильно. console.log (newArray);

+2

Можете ли вы показать нам, где вы застряли? –

+0

Ваша проблема в _newArray [c] .sum + data [i] [j] .sum; _ вам нужно + = добавить, а не просто +. Использование только оператора + выполняет операцию, но нигде не сохраняется. – Robin

+0

мой плохой! Я поместил свой код и то, что мне не хватало, это знак = 0 на этой строке "newArray [c] .sum + data [i] [j] .sum;" :( – diegoddox

ответ

0

Ваша проблема заключается в линии

newArray[c].sum + data[i][j].sum; 

Эта линия выполняет вычисление, но оно не хранится в newArray. Если вы измените оператор на + =, ваша функция будет работать правильно.

newArray[c].sum + data[i][j].sum; // Sums the two values 
newArray[c].sum += data[i][j].sum; // Sums and saves them to newArray[c].sum 

Правильное решение показано здесь в this jsFiddle.

var newArray = []; 
for(var i = 0; i < data.length; i++){ 
    var objects = data[i]; 
    for(var n = 0; n < objects.length; n++){ 
     var existed = false; 
     for(var z = 0; z < newArray.length; z++){ 
      if(newArray[z].field === objects[n].field){ 
       newArray[z].sum += objects[n].sum; 
       existed = true; 
      } 
     } 
     if(!existed){ 
      newArray.push({field : objects[n].field, sum: objects[n].sum});     
     } 
    } 
} 

Вы цикл по всем элементам, а затем суммировать их в новый массив называется newArray. Он выглядит, если объект с полем уже существует, и если он это делает, добавляет сумму к существующему элементу. Если нет, он создает новый элемент с значением поля и начальной суммой.

+0

Хороший ответ .. но постарайтесь подождать, пока один обновит код, а затем ответьте. :) Или иначе он побуждает людей загружать вопрос, даже не предпринимая никаких усилий. –

+1

Спасибо за ваш ответ @Robin и извините за не предоставление моего код. Мне не хватало «=» на моем коде. – diegoddox

0

просто посмотреть на этот код

<script> 
    var data = [ 
     [ 
     {field: 123, sum: 100}, 
     {field: 345, sum: 98} 
     ],[ 
     {field: 123, sum: 12}, 
     {field: 345, sum: 20} 
     ] 
    ]; 


var o=[]; 
var j=0; 


while(j<data.length) 
{ 
    var obj1={}; 
    var field; sum=0; 
    for(i=0; i<data.length; i++) 
    { 
     field=data[i][j].field; 
     sum=sum+data[i][j].sum; 
    } 
    obj1.field=field; 
    obj1.sum=sum; 
    o.push(obj1); 
    j++; 
} 

console.log(o) 

    </script> 
1

раствор ECMAScript6 (если таковые имеются):

data 
    .reduce((a, b) => a.concat(b)) 
    .reduce((a, b) => { 
     var idx = a.findIndex(elem => elem.field == b.field); 
     if (~idx) { 
      a[idx].sum += b.sum; 
     } 
     else { 
      a.push(JSON.parse(JSON.stringify(b))); 
     } 
     return a; 
    }, []); 

Ваш вопрос просто опечатка, хотя:

- newArray[c].sum + data[i][j].sum 
+ newArray[c].sum += data[i][j].sum 
2

В функциональной программирование, это будет классическая проблема с уменьшением карты, или, более конкретно, сокращение по ключу.

Если вы работаете с underscore, вы могли бы сделать что-то вроде этого:

var op = _.chain(data) 
//first put it all in one array 
.flatten() 
//then group by the field 
.groupBy(function(item){return item.field;}) 
//then sum up all of the "sum" properties 
.mapObject(function(val,key){ 
    return _.reduce(val, function(total,sum){ 
     return total + sum.sum; 
    },0); 
}) 
//then map it back into our original data structure 
.pairs() 
.map(function(item){ 
    return {field: item[0], sum: item[1]}; 
}); 
Смежные вопросы