-2

I'm trying to sort some json in js. And I'm trying to sort by the sum of "numbers", in a descending order. So for this data, the second row data would be first, since the sum of "numbers" is larger. I figured out how to sort by anything else, but not by the sum.

{
   "rows":[
      {
         "key":0,
         "name":"whitelilac",
         "numbers":[
            10,
            40,
            5
         ],
         "options":[
            "yes",
            "no",
            "maybe"
         ],
         "comment":"content"
      },
      {
         "key":1,
         "name":"blacklilac",
         "numbers":[
            5000,
            10,
            20
         ],
         "options":[
            "yes",
            "no",
            "maybe"
         ],
         "comment":"content"
      }
   ],
   "more":false
}
  • So did you attempt anything? – epascarello Jun 29 '20 at 22:03
  • 1
    Do know how to compute the sum of an array? If you can do that, why can't you just sort by that? – Barmar Jun 29 '20 at 22:04
  • See https://stackoverflow.com/questions/1230233/how-to-find-the-sum-of-an-array-of-numbers for how to calculate the sum of an array. – Barmar Jun 29 '20 at 22:04
  • This was my last attempt at sorting, which works for every key but "numbers": `function sortResults(prop, dec) {` `data.rows.sort(function(a, b) {` `if (dec) {` `return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);` `} else {` `return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);` `}` `});` `}` Can't make it work with `array.reduce((a, b) => a + b, 0)` basically. – WhiteLilac Jun 29 '20 at 22:08

3 Answers3

1

First, we need to know how to calculate the sum of an Array of numbers. We can do that using reduce:

const numbers = [1, 2, 3];

const res = numbers.reduce((sum, n) => sum + n);

console.log(res); // 6

Then, we need to know how to sort an Array based on a function (with sort), and this is it:

const obj = {rows:[{key:0,name:"whitelilac",numbers:[10,40,5],options:["yes","no","maybe"],comment:"content"},{key:1,name:"blacklilac",numbers:[5e3,10,20],options:["yes","no","maybe"],comment:"content"}],more:!1};

function sumArray(arr) {
  return arr.reduce((sum, n) => sum + n);
}

function sortBySum(a, b) {
  return sumArray(b.numbers) - sumArray(a.numbers);
}

obj.rows.sort(sortBySum);

document.body.innerHTML = `<pre>${JSON.stringify(obj, 0, 2)}</pre>`;

If you don't want to mutate the original Object, you can use this trick:

const obj = {rows:[{key:0,name:"whitelilac",numbers:[10,40,5],options:["yes","no","maybe"],comment:"content"},{key:1,name:"blacklilac",numbers:[5e3,10,20],options:["yes","no","maybe"],comment:"content"}],more:!1};

function sumArray(arr) {
  return arr.reduce((sum, n) => sum + n);
}

function sortBySum(a, b) {
  return sumArray(b.numbers) - sumArray(a.numbers);
}

const sortedRows = [].concat(obj.rows).sort(sortBySum);

document.body.innerHTML = `
<h1>Original obj (unmodified)</h1>
<pre>${JSON.stringify(obj, 0, 2)}</pre>
<h1>Sorted rows array</h1>
<pre>${JSON.stringify(sortedRows, 0, 2)}</pre>
`;
blex
  • 24,941
  • 5
  • 39
  • 72
0

Solution

Support your JSON is available in data variable.

Use reduce and sort functions to get your desired output.

const data = {"rows":[{"key":0,"name":"whitelilac","numbers":[10,40,5],"options":["yes","no","maybe"],"comment":"content"},{"key":1,"name":"blacklilac","numbers":[5000,10,20],"options":["yes","no","maybe"],"comment":"content"}],"more":false};

const sum = el => el.reduce((sum, item) => sum + item);

data.rows.sort((a, b) => sum(a.numbers) - sum(b.numbers)); // ascending sort
console.log(data);

data.rows.sort((a, b) => sum(b.numbers) - sum(a.numbers)); // descending sort
console.log(data);
Hamza Rashid
  • 1,329
  • 15
  • 22
-1

Use JS sort() & you can write your own custom comparison function: Ex-

obj.rows.sort(function(first, second){
//calc sum of numbers 
//return sumOfFirst - sumOfSecond 
}
)
Anshul
  • 94
  • 4