Как использовать reduce для подсчета минимума, максимума и среднего в JavaScript массивах

Помогите с подсчетом статистики по оценкам

У меня есть два массива с данными о тестах и оценках учеников. Нужно создать таблицу со статистикой для каждого теста.

const testsList = [
  {testCode: 'test1', testTitle: 'Контрольная №1'},
  {testCode: 'test2', testTitle: 'Контрольная №2'},
  {testCode: 'test3', testTitle: 'Контрольная №3'},
  {testCode: 'test4', testTitle: 'Итоговая работа'},
]

const studentResults = [
  {recordId: 'rec01', testCode: 'test1', pupilId: 'st1', score: 65},
  {recordId: 'rec02', testCode: 'test1', pupilId: 'st2', score: 72},
  {recordId: 'rec03', testCode: 'test1', pupilId: 'st3', score: 88},
  {recordId: 'rec04', testCode: 'test1', pupilId: 'st4', score: 79},
  {recordId: 'rec05', testCode: 'test2', pupilId: 'st1', score: 91},
  {recordId: 'rec06', testCode: 'test2', pupilId: 'st2', score: 86},
  {recordId: 'rec07', testCode: 'test2', pupilId: 'st3', score: 74},
]

Я начал писать функцию с reduce, но застрял на функциях для поиска минимума, максимума и среднего значения:

const calculateStats = (tests, results) => {
  const getCount = (results, testId) => {
    return results.reduce((count, item) => {
      if (testId === item.testCode) {
        count++;
      }
      return count;
    }, 0);
  }

  const getMinScore = (results, testId) => {
     // Тут нужна помощь
  }

  const getMaxScore = (results, testId) => {
     // И тут тоже
  }

  const getAvgScore = (results, testId) => {
     // И здесь
  }

  return tests.reduce((acc, test) => {
    const testId = test.testCode
    const count = getCount(results, testId)
    const minScore = getMinScore(results, testId)
    const maxScore = getMaxScore(results, testId)
    const avgScore = getAvgScore(results, testId)

    return {
      ...acc,
      [test.testTitle]: {
        count,
        minScore,
        maxScore,
        avgScore
      }
    }
  }, {})
}

Хочу получить примерно такой результат:

Контрольная №1: количество: 4, мин: 65, макс: 88, среднее: 76
Контрольная №2: количество: 3, мин: 74, макс: 91, среднее: 83.67

Буду благодарен за любую помощь! Может быть есть более простой способ решить эту задачу?

Для getMinScore и getMaxScore делай так: собери все оценки для теста, потом используй Math.min/Math.max со spread оператором. Вот: const scores = results.filter(r => r.testCode === testId).map(r => r.score); return Math.min(...scores). Для среднего - сумма через reduce, дели на длину массива. Только не забудь проверить пустой массив, иначе получишь NaN.

Можно еще проще - объедини всю логику в один reduce для каждого метода. Для getMinScore: return results.reduce((min, item) => item.testCode === testId ? Math.min(min, item.score) : min, Infinity). Для максимума то же самое, только Math.max. Для среднего собери сумму и количество за один проход: const {sum, count} = results.reduce((acc, item) => item.testCode === testId ? {sum: acc.sum + item.score, count: acc.count + 1} : acc, {sum: 0, count: 0}); return sum / count. Только не забудь проверить деление на ноль.

Попробуй так для getMinScore: return results.filter(item => item.testCode === testId).reduce((min, item) => Math.min(min, item.score), Infinity) Для максимума просто замени Math.min на Math.max. Для среднего отфильтруй все оценки, посчитай сумму через reduce и раздели на длину массива. Можно всё в одном reduce запихнуть, но твой способ понятнее.