Sorting a JavaScript array by summing the same elements

I'm having trouble trying to sort and group the elements of an array in JavaScript. Here's an example of input:

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

      

The result I am trying to achieve:

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

      

I would like to sort it by branchName, for example, to sum the total for one branchName and then link all other attributes like merchantName and branchAddress along with it so 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);
        }

      

Actually I have no idea how to start it. Any ideas how to achieve it?

Thanks, advanced!

+3


source to share


3 answers


So, this is how I would do it:

  • Group the array in hashmap

    based on property branchName

    - calculate the total along with that.

  • Take the array out hashmap

    and sort them

See the 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;}
      

Run code


+4


source


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);
      

Run code


+2


source


It looks like you want to do 2 things: sort by branch name and then output one value for each branch name (deduplicate results / group -by branchName).

There are several potential problems. 1) your example shown above is not sorted by branchName, although you stated that: a) you wanted it sorted by branchName and b) that this would be an example. Secondly, the output is not completely deterministic - in particular, it seems that you are just outputting the first corresponding form of the branchName, and thus the value for a generic property that depends on the records for the same branch name is that that is shown. So ... assuming you A) want the results to be sorted, and B) don't care about the value of the "common" attribute, this can be done fairly easily with:

I) Sorting the array. See https://gist.github.com/umidjons/9614157 for an example: just write a comparison function that compares the values ​​of branchName. And also, II) Number the results by simply printing the first record whenever the branch name changes from the previous value.

0


source







All Articles