Сортировать по сумме массива в объекте - PullRequest
0 голосов
/ 14 июня 2019

Я ищу решение для сортировки массива по сумме свойства массива в объекте.

Например, если основной массив равен

[
  {
    "Grid": {
       "Day": [
          11,
          12
       ]
     },
     "Name": "One"
  },
  {
    "Grid": {
       "Day": [
          5,
          2
       ]
     },
     "Name": "Two"
   }
]

Как можно отсортировать сумму Day, чтобы вернуть как

[
  {
    "Grid": {
       "Day": [
          5,
          2
       ]
     },
     "Name": "Two"
  },
  {
    "Grid": {
       "Day": [
          11,
          12
       ]
     },
     "Name": "One"
   }
]

Ответы [ 4 ]

3 голосов
/ 14 июня 2019

Вы можете использовать комбинацию reduce для суммирования массива и sort для упорядочения вывода:

var input = [
  {
    "Grid": {
       "Day": [
          11,
          12
       ]
     },
     "Name": "One"
  },
  {
    "Grid": {
       "Day": [
          5,
          2
       ]
     },
     "Name": "Two"
   }
];


var result = input.sort( (a,b) =>  sumOfDay(a) - sumOfDay(b));
console.log(result);

function sumOfDay(obj){
    return obj.Grid.Day.reduce( (acc,curr) => acc + curr, 0);
}

Обратите внимание, что Array.prototype.sort фактически изменяет исходный массив на месте.таким образом, вышеприведенное также может сделать

input.sort( (a,b) =>  sumOfDay(a) - sumOfDay(b));
console.log(input);

Итак, не попадайтесь в ловушку, думая, что исходный массив не изменился только потому, что я присвоил результат result! *

ЕслиВы хотите отсортировать копию массива, сделайте это:

var result = input.slice().sort( (a,b) =>  sumOfDay(a) - sumOfDay(b));
2 голосов
/ 14 июня 2019

Вам просто нужно sort ваш массив с компаратором, который использует reduce для вычисления суммы значений внутреннего массива:

let arr = [{"Grid": {"Day": [11,12]}, "Name": "One"},
           {"Grid": {"Day": [5,2]}, "Name": "Two"},
           {"Grid": {"Day": [1,2]}, "Name": "Two"}];
           
let sum = el => el.Grid.Day.reduce((a,b) => a + b);
arr.sort((a,b) => sum(a) - sum(b));

console.log(arr)
0 голосов
/ 14 июня 2019

Просто «другой» подход к решению проблемы: если вам (когда-нибудь, позже, в конце концов, возможно) потребуется выполнить повторную сортировку, хорошим подходом может быть также добавление свойства к каждому элементу сетки, содержащему сумму дней, избегая вызов .reduce каждый раз, когда вам нужно отсортировать массив.

В этом подходе .forEach используется для создания нового свойства (через .reduce), а затем .sort используется для сортировки массива на месте.

const input = [
  {
    "Grid": {
       "Day": [
          11,
          12
       ]
     },
     "Name": "One"
  },
  {
    "Grid": {
       "Day": [
          5,
          2
       ]
     },
     "Name": "Two"
   }
];
// Add a DaySum property evaluating the sum of the days.
input.forEach(i => i.Grid.DaySum = i.Grid.Day.reduce((a,b) => a + b));
//                                                                 ^--- the second parameter (initial value) is unneeded here due to the fact that all elements are actually numeric, hence if the initial value is the first element of the array, which is a number already.
// Sor the array by that property.
input.sort((a,b) => a.Grid.DaySum - b.Grid.DaySum);
console.log(input);

Или, как предлагает @Andreas ниже, вы можете напрямую назначить свойство при сортировке:

const input = [
  {
    "Grid": {
       "Day": [
          11,
          12
       ]
     },
     "Name": "One"
  },
  {
    "Grid": {
       "Day": [
          5,
          2
       ]
     },
     "Name": "Two"
   }
];

const sum = (a,b) => a + b;
input.sort((a,b) => {
  a.Grid.DaySum = a.Grid.DaySum || a.Grid.Day.reduce(sum);
  b.Grid.DaySum = b.Grid.DaySum || b.Grid.Day.reduce(sum);
  return a.Grid.DaySum - b.Grid.DaySum;
});
console.log(input);
0 голосов
/ 14 июня 2019

Создайте новый массив a, сопоставив его и используя reduce в массиве Day Grid, чтобы получить сумму, которую вы можете сравнить в sort, чтобы вернуть список, отсортированный по сумме. дней.

const a = [
  {
    "Grid": {
       "Day": [
          11,
          12
       ]
     },
     "Name": "One"
  },
  {
    "Grid": {
       "Day": [
          5,
          2
       ]
     },
     "Name": "Two"
   }
]

const daySum = ({Grid}) => Grid.Day.reduce((prev, curr) => prev+curr, 0)

const sorted = [...a].sort(daySum)

console.log(sorted)
console.log(a) //Original array intact
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...