简体   繁体   中英

JavaScript array sorting by summing up same elements

I was having some trouble when trying to sort and group the array items in JavaScript. Here is the sample inputs:

var arr = [
{merchantName: '', branchName: 'e', branchAddress: '', total: 10.5},
];

The output that I am trying to achieve:

var arr = [
{merchantName: '', branchName: '', branchAddress: '', total: 10.5},
];

I wanted to sort it in by branchName, for instance sum up the total for same branchName then at the same time bind all other attributes like merchantName and branchAddress together with it so that I can access them like:

for(var i = 0; i < arr.length; i++){
            console.log(arr[i].merchantName + ' ' + arr[i].branchName + ' ' + arr[i].branchAddress + ' ' + arr[i].total);
        }

I actually have no idea on how to even start it. Any ideas how to achieve it?

Thanks in advanced!

So here is how I would do it:

  1. Group the array into a hashmap based on the branchName property - calculate the total along with this.

  2. Take out the array from the hashmap and sort them

See demo below:

 var arr = [ {merchantName: 'Giant', branchName: 'Giant Marine', branchAddress: 'Terrace 56 Branch Blk 56 Marine Terrace #01-259/261 Singapore 440056', total: 10.5}, {merchantName: 'Ntuc', branchName: 'Ntuc Zhongshan Mall Branch', branchAddress: ' Zhongshan Mall Balestier #02-01, 20 Ah Hood Road, 329984', total: 12.149999999999999}, {merchantName: 'Giant', branchName: 'Giant Kim Keat 260 Branch', branchAddress: ' Blk 260 Kim Keat Avenue #01-01 Singapore 310260', total: 5.1}, {merchantName: 'Ntuc', branchName: 'Ntuc Scotts Square Branch', branchAddress: ' Scotts Square #B1-03 To 07 & #B1-10, 6 Scotts Road, 228209', total: 4}, {merchantName: 'Ntuc', branchName: 'Ntuc Zhongshan Mall Branch', branchAddress: ' Zhongshan Mall Balestier #02-01, 20 Ah Hood Road, 329984', total: 4}, {merchantName: 'Ntuc', branchName: 'Ntuc Zhongshan Mall Branch', branchAddress: ' Zhongshan Mall Balestier #02-01, 20 Ah Hood Road, 329984', total: 8} ]; // create a hashmap var hash = arr.reduce(function(p,c){ if(!p[c.branchName]) p[c.branchName] = c; else p[c.branchName].total += c.total; return p; }, Object.create(null)) // now extract the result and sort them var result = Object.keys(hash).map(function(e){ return hash[e]; }).sort(function(a,b){ return a.branchName - b.branchName; }); console.log(result); 
 .as-console-wrapper{top:0;max-height:100%!important;} 

A solution using reduce()

 var arr = [{ merchantName: 'Giant', branchName: 'Giant Marine', branchAddress: 'Terrace 56 Branch Blk 56 Marine Terrace #01-259/261 Singapore 440056', total: 10.5 }, { merchantName: 'Ntuc', branchName: 'Ntuc Zhongshan Mall Branch', branchAddress: ' Zhongshan Mall Balestier #02-01, 20 Ah Hood Road, 329984', total: 12.149999999999999 }, { merchantName: 'Giant', branchName: 'Giant Kim Keat 260 Branch', branchAddress: ' Blk 260 Kim Keat Avenue #01-01 Singapore 310260', total: 5.1 }, { merchantName: 'Ntuc', branchName: 'Ntuc Scotts Square Branch', branchAddress: ' Scotts Square #B1-03 To 07 & #B1-10, 6 Scotts Road, 228209', total: 4 }, { merchantName: 'Ntuc', branchName: 'Ntuc Zhongshan Mall Branch', branchAddress: ' Zhongshan Mall Balestier #02-01, 20 Ah Hood Road, 329984', total: 4 }, { merchantName: 'Ntuc', branchName: 'Ntuc Zhongshan Mall Branch', branchAddress: ' Zhongshan Mall Balestier #02-01, 20 Ah Hood Road, 329984', total: 8 } ]; var newArr = arr.reduce(function(items, item) { var existing = items.find(function(i) { return i.branchName === item.branchName; }); if (existing) { existing.total += item.total; } else { items.push(item); } return items; }, []); console.log(newArr); 

Looks like you're wanting to do 2 things: sort by the branchName and then output a single value for each branchName (de-duplicate the results / group-by branchName).

There are a couple of potential issues. 1) your example output shown above isn't sorted by branchName, even though you stated that a) you wanted it to be sorted by branchName, and b) that this would be an example. Second, the output is not entirely deterministic - in particular it seems you just output the first matching record form branchName and thus the value for the total property - which varies among the records for the same branchName - is what is shown. So... assuming you A) want the results sorted, and B) don't care about the value of the "total" attribute, this can be done pretty easily via:

I) Sort the array. See https://gist.github.com/umidjons/9614157 for an example: just write a comparison function that compares branchName values. And, II) Loop through the results, just outputing the first record whenever the branchName changes from the previous value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM