Суммирование и сортировка двумерного массива

Суть задачи в том, что у нас есть двойной массив, имеющий в себе имена и числа, выпавшие за бросок кубика, за каждый отдельный ход. Нужно найти сумму очков у каждого игрока и вывести того, кто набрал больше всего баллов.

Пример: [[name_1, 1,2,3,4],[name_2, 2,3,6,5]]

Следовательно, выводит следующее: [name_2,16]

const data = [
  ['name_1', 1, 2, 3, 4],
  ['name_2', 2, 3, 6, 5]
];

const main = (players_data) => {
  function alg() {
    let arr = [
      []
    ]
    for (let i = 0, i < players_data.length, i++) {
      let c = 0
      for (let j = 0, j < 5, j++) {
        if (j == 0) {
          arr.push([players_data[i][0]])
        } else {
          c = c + (10 - players_data[i][j])
        }
      }
      arr.push([c])
    }
    arr.forEach(row => row.sort(1));
  }
  return (arr[0])
};

console.log(main(data)) // expected [name_2,16]

Я решил попробовать двойной перебор, создав новый двойной массив, в который рассчитанные значение, а позже попытался сделать двойную сортировку.


Ответы (1 шт):

Автор решения: SwaD

Вот таким скриптом можно пробежаться по массиву массивов, посчитать для каждого вложенного массива количество очков, отсортировать массив по убыванию и вывести элемент(игрока) с максимальным числом очков.

const initArr = [
  ['name_1', 1, 2, 3, 4],
  ['name_2', 2, 3, 6, 5]
];

function whoWin(arr) {
  // Преобразуем полученные данные для каждого элемента
  return arr.reduce((acc, item) => {
      // Считаем сумму очков, начиная со второго элемента
      const sum = item.reduce((sum, it, idx) => idx ? sum + it : 0, 0);
      // Возвращаем массив массивов нужного вида [name, sum]
      return [...acc, [item[0], sum]];
    }, [])
    // Сортируем по очкам(второй элемент) и возвращаем 1й элемент
    .sort((a, b) => b[1] - a[1])[0];
}

console.log(whoWin(initArr));

Данный код не учитывает варианты, если будет несколько игроков с одинаковым количеством максимальных очков.

Наверное в примере выше, первый reduce перебор, поэтому вот с методом .map(Он, наверное, более логичнее подходит для решения данной задачи)

const initArr = [['name_1', 1,2,3,4],['name_2', 2,3,6,5]];

function whoWin(arr) {
  // Преобразуем полученные данные для каждого элемента
  return arr.map((item) => {
    // Считаем сумму очков, начиная со второго элемента
    const sum = item.reduce((sum, it, idx) => idx ? sum + it : 0, 0);
    // Возвращаем массив нужного вида [name, sum]
    return [item[0], sum];
  })
    // Сортируем по очкам(второй элемент) и возвращаем 1й элемент
    .sort((a,b)  => b[1] - a[1])[0];
}

console.log(whoWin(initArr));

Если методы массивов еще не осваивали, то вот такой же код с помощью циклов for

const initArr = [
  ['name_1', 1, 2, 3, 4],
  ['name_2', 2, 3, 6, 5]
];

function whoWin(arr) {
  // Создаем новый массив
  const resultArr = [];
  // Обходим каждый элемент массива
  for (let i = 0; i < arr.length; i++) {
    // Создаем внутренний массив. Первым элементом кладем имя, вторым сумму = 0
    const sumPlayer = [arr[i][0], 0];
    // Начиная со второго элемента считаем сумму очков
    for (let j = 1; j < arr[i].length; j++) {
      // Суммируем с помощью оператор +=
      sumPlayer[1] += arr[i][j];
    }
    // Пушим полученный массив [name, sum] в результирующий
    resultArr.push(sumPlayer);
  }
  // Результирующий сортируем по очкам
  resultArr.sort((a, b) => b[1] - a[1]);
  // Возвращтаем первый элемент
  return resultArr[0];
}

console.log(whoWin(initArr));

UPD: По комментариям, добавляю функцию с небольшой оптимизацией, позволяющую отказаться от сортировки массива

const initArr = [['name_1', 1,2,3,4],['name_2', 2,3,6,5]];

function whoWin(arr) {
  let result = ['', 0];
  arr.forEach(item => {
    const sum = item.reduce((sum, it, idx) => idx ? sum + it : 0, 0);
    if (sum > result[1]) result = [item[0], sum];
  })
  return result;
}

console.log(whoWin(initArr));

Ну и без дополнительных переменных

const initArr = [
  ['name_1', 1, 2, 3, 4],
  ['name_2', 2, 3, 6, 5]
];

function whoWin(arr) {
  return arr.reduce((acc, item) => {
    const sum = item.reduce((sum, it, idx) => idx ? sum + it : 0, 0);
    if (sum > acc[1]) acc = [item[0], sum];
    return acc;
  }, ['', 0]);
}

console.log(whoWin(initArr));

→ Ссылка