Javascript multiple matching abbreviations / summation of array

What is the cleanest way to reduce this array?

data = { id: [1, 1, 1, 3, 3, 4, 5, 5, 5, ...] v: [10,10,10, 5, 10 ...] } 

For each id, there is a corresponding v. I want to sum v for each identifier. In this example, the result should be

 data = { id: [1, 3, 4, 5, ...] v: [30, 15, ...] } 
+6
source share
7 answers

I would like to find Array.prototype.reduce () , a simple and elegant solution

 var ids = [1, 1, 1, 3, 3, 3, 3, 4, 5, 6, 6, 6], v = [10, 10, 10, 5, 10, 10, 10, 404, 505, 600, 60, 6], data = {}; data.v = []; data.ids = ids.reduce(function(a, b, index) { if (a.indexOf(b) < 0) a.push(b); if (!data.v[a.indexOf(b)]) data.v[a.indexOf(b)] = 0; data.v[a.indexOf(b)] += v[index]; return a; }, []); 

https://jsfiddle.net/2ssbngLr/

+3
source

One way to do this, given two arrays of equal length, would be to display / reduce them:

 const ids = [1, 1, 1, 3, 3]; const vs = [10,10,10,5,10]; const reduced = ids .map((val, i) => ({ id: val, value: vs[i] })) .reduce((agg, next) => { agg[next.id] = (agg[next.id] || 0) + next.value; return agg; }, {}); console.log(reduced); // Object {1: 30, 3: 15} 

Working example: https://jsfiddle.net/h1o5rker/1/

+3
source

I think that this can be done by reducing

  var data = { id: [1, 1, 1, 3, 3], v: [10, 10, 10, 5, 10] } var sumsObjs = data.v.reduce(function(sum, val, index) { var id = data.id[index]; if (sum[id] !== undefined) { sum[id] = sum[id] + val; } else { sum[id] = val; } return sum; }, {}); console.log(sumsObjs); 
 <script src="https://getfirebug.com/firebug-lite-debug.js"></script> 
+2
source

 var data={ id: [1,1,1,10,123,4531], v:[123,123,53,223,11,11,11] }, _v = data.v, vinit; document.write(data.v+'<br>'); for(var i=0;i<_v.length;i++){ vinit = _v[i]; for(var j=i+1; j<=_v.length;j++){ if(_v[j]===vinit){ delete _v[j]; } } }; document.write(data.v); 
 var data={ id: [1,1,1,10,123,4531], v:[123,123,53,223,11,11,11,...] }, _v = data.v, vinit; for(var i=0;i<_v.length;i++){ vinit = _v[i]; for(var j=i+1; j<=_v.length;j++){ if(_v[j]===vinit){ delete _v[j]; } } } 

the above code is only for v, but you can reduce duplicate elements for id at the same time by introducing a few more variables

in the fragment you will see that in the second line there are additional commas that indicate that these elements have been deleted.

+1
source

If the identifiers are always in order, a simple loop can solve this problem. No need to get too complicated.

 data = { id: [1, 1, 1, 3, 3, 4, 5, 5, 5], v: [10, 10, 10, 5, 10, 1, 2, 3, 4] }; var result = { id: [], v: [] }; (function() { var ids = data.id, vals = data.v, lastId = ids[0], runningTotal = vals[0]; for (var i = 1; i < ids.length; i++) { if (lastId === ids[i]) { runningTotal += vals[i]; } if (lastId !== ids[i] || i + 1 === ids.length) { result.id.push(lastId); result.v.push(runningTotal); lastId = ids[i]; runningTotal = vals[i]; } } }()); console.log(result); 
+1
source

Some people have already posted good solutions, but I really have not seen what does exactly what you are looking for. Here is the one that takes your specific object and returns an object of the same format, but meeting your requirements and scaled down.

 // Your data object data = { id: [1, 1, 1, 3, 3], v: [10,10,10, 5, 10] } // Assuming obj consists of `id` and `v` function reduce(obj){ // We create our reduced object var reducedObj = { id: [], v: [] } // Next we create a hash map to store keys and values var map = {}; for(var i=0; i<obj.id.length; ++i){ // If this key doesn't exist, create it and give it a value if(typeof map[parseInt(obj.id[i])] === 'undefined'){ map[parseInt(obj.id[i])] = 0; } // Sum all of the values together for each key map[parseInt(obj.id[i])] += parseInt(obj.v[i]); } // Now we map back our hashmap to our reduced object for(var ele in map){ reducedObj.id.push(ele); reducedObj.v.push(map[ele]); } // Return our new reduced object return reducedObj; } var myReducedObject = reduce(data); console.log(myReducedObject); 

Working script

+1
source

This is a solution for ordered id with Array.prototype.reduce() .

 var data = { id: [1, 1, 1, 3, 3, 4, 5, 5, 5], v: [10, 10, 10, 5, 10, 7, 8, 10, 13] }, result = { id: [], v: [] }; data.id.reduce(function (r, a, i) { if (r === a) { result.v[result.v.length - 1] += data.v[i]; } else { result.id.push(a); result.v.push(data.v[i]); } return a; }, -1); document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>'); 

Or in-situ version

 var data = { id: [1, 1, 1, 3, 3, 4, 5, 5, 5], v: [10, 10, 10, 5, 10, 7, 8, 10, 13] }; void function (d) { var i = 1; while (i < d.id.length) { if (d.id[i - 1] === d.id[i]) { d.id.splice(i, 1); dv[i - 1] += dvsplice(i, 1)[0]; continue; } i++; } }(data); document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>'); 
+1
source

All Articles