Неточное среднее значение из функции JavaScript - PullRequest
0 голосов
/ 10 марта 2019

У меня есть метод average() для вычисления среднего между двумя значениями. Средние значения получаются с помощью "волоска" десятичного значения.

const measurements = [ 
  { timestamp: '2015-09-01T16:00:00.000Z',
    temperature: 27.1,
    dewPoint: 16.9 
  },
  { timestamp: '2015-09-01T16:10:00.000Z',
    temperature: 27.3,
    dewPoint: 0 
  },
  { timestamp: '2015-09-01T16:20:00.000Z',
    temperature: 27.5,
    dewPoint: 17.1 
   },
   { timestamp: '2015-09-01T16:30:00.000Z',
    temperature: 27.4,
    dewPoint: 17.3 
   },
   { timestamp: '2015-09-01T16:40:00.000Z',
    temperature: 27.2,
    dewPoint: 0 
   },
   { timestamp: '2015-09-01T17:00:00.000Z',
    temperature: 28.1,
    dewPoint: 18.3 
   } 
] 

Для краткости, я не собираюсь делиться здесь 60 строками кода:

Предположения:

  • У меня есть query() метод для получения диапазонов и от отметки времени. В моем примере от 2015-09-01T16:00:00.000Z до 2015-09-01T17:00:00.000Z

  • Другой метод перебирает объект и выводит min и max значения с указанной метрикой . Моя метрика: dewPoint min и max Значения вышеуказанного массива 16.9 и 18.3 соответственно.

  • Наконец (см. Ниже) метод для получения среднего значения между min и max значениями

Поэтому это результат объяснения выше:


// POSTMAN result

[
    {
        "metric": "dewPoint",
        "stat": "min",
        "value": 16.9
    },
    {
        "metric": "dewPoint",
        "stat": "max",
        "value": 18.3
    },
    {
        "metric": "dewPoint",
        "stat": "average",
        "value": 17.4
    }
]

Я хочу получить среднее значение между максимальным и минимальным значениями. то есть 16.9 & 18.3, который должен быть 17,6 , однако я получаю 17,4 вместо

Вот один метод, который имеет реальную ошибку.

function averageMetric(measurements, metric) {

  // => metric dewPoint
  // => measurements = the data array in example

  let value = 0
  let measurementsWithMetric = 0
  measurements.forEach(measurement => {
    if (measurement[metric]) {
      value += measurement[metric]
      measurementsWithMetric++
    }
  })
  //=> value = 69.6
  //=> measurementsWithMetric = 4
  const average = value / measurementsWithMetric // Is this the issue?
  // average =  17.4

  return isNaN(average) ? null : Math.round(average * 100) / 100
}

Не могли бы вы помочь мне понять проблему здесь, а также предложить решение, эквивалентное ES6, описанным выше способом?

Ответы [ 2 ]

2 голосов
/ 10 марта 2019

Ваша функция вычисляет среднее арифметическое , а не средний диапазон . Вот функция для вычисления этого:

const measurements = [ 
  {temperature: 27.1, dewPoint: 16.9},
  {temperature: 27.3, dewPoint: 0}, // Isn't this the minimum value though?
  {temperature: 27.5, dewPoint: 17.1},
  {temperature: 27.4, dewPoint: 17.3},
  {temperature: 27.2, dewPoint: 0},
  {temperature: 28.1, dewPoint: 18.3}, 
  {temperature: 28.2} 
];
function averageMetric(meas, metr) {
  const valid = meas.filter(e => e[metr]);
  const min = Math.min(...valid.map(e => e[metr]));
  const max = Math.max(...valid.map(e => e[metr]));
  return (min + max) / 2;
}

console.log(averageMetric(measurements, 'dewPoint'));
0 голосов
/ 10 марта 2019
measurements.forEach(measurement => {
  if (measurement[metric]) {
    value += measurement[metric]
    measurementsWithMetric++
  }
})

неверно, если вы хотите получить среднее значение минимального и максимального значений (что соответствует среднему диапазону)

Вместо этого вам следует попробовать

let min = 10**6, max = -10**6; //unless your dew point is stupid this should be fine
measurements.forEach(measurement => {
  if (measurement[metric]) {
    min = Math.min(measurement[metric], min);
    max = Math.max(measurement[metric], max);
    measurementsWithMetric++
  }
})
let average = (max+min)/2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...