Javascript-尝试将数据不变地添加到映射中的数组,但接收到空数组

时间:2019-07-25 16:38:00

标签: javascript arrays immutability

我有一个函数试图映射对象数组。对于数组中的每个项目,我想计算一定的平均值,然后将该数据弹出到另一个数组中。在函数的结尾,我想返回一个数组,该数组现在包含在映射期间接收到的数据。

相反,我要返回一个空数组。

我试图这样做而不改变数组,所以避免使用Array.push()(我会注意到,如果确实在函数中使用Array.push来更新我的数组,则该函数可以正常工作)。

这是有问题的功能:

function getForecastAverages(forecasts) {
  const dailyForecasts = Object.values(forecasts);
  const averages = [];
  dailyForecasts.map((hourlyForecasts, idx) => {
    const high = getTempAvg(hourlyForecasts, 'high');
    const low = getTempAvg(hourlyForecasts, 'low');
    const desc = getDescriptionAvg(hourlyForecasts);

    return [...averages,  { date: Object.keys(forecasts)[idx], high, low, desc }];
  });

  return averages;
}

其他功能

function getTempAvg(forecasts, key) {
  const avg = forecasts.reduce((acc, curr) => acc + curr[key], 0) / forecasts.length;

  return avg.toFixed(2);
}

function getDescriptionAvg(forecasts) {
  const length = forecasts.length;
  const descriptions = forecasts.map(forecast => forecast.description);

  return getMostFrequent(descriptions, length, 0);
}

function getMostFrequent(array, length, currIdx, maxCount = 0, mostFrequent = null, counts = {}) {
  if (currIdx + 1 > length) return mostFrequent;

  // first we need the word that we are counting the frequency of in the array
  const word = array[currIdx];

  // check if the current word exists in our counts object. If it doesn't, add the word and its count to the object. If it is present we increase its current count by 1
  if (counts[word] === undefined) {
    counts[word] = 1;
  } else {
    counts[word] = counts[word] + 1;
  }

  // check if the current word has a count that is larger than the highest count in our object. If it does we want to update our max count and most frequent word
  if (counts[word] > maxCount) {
    maxCount = counts[word];
    mostFrequent = word;
  }
  const newIdx = currIdx + 1;

  return getMostFrequent(array, length, newIdx, maxCount, mostFrequent, counts);
}

虚拟数据

forecasts = {
  '2019-07-25': [
    {
      date: '2019-07-25 18:00:00',
      description: 'broken clouds',
      grnd_level: 1006.19,
      high: 24.64,
      humidity: 49,
      low: 23.98,
      pressure: 1017.03,
      sea_level: 1017.03,
      temp: 24.64,
    },
    {
      date: '2019-07-25 21:00:00',
      description: 'overcast clouds',
      grnd_level: 1006.34,
      high: 22.91,
      humidity: 55,
      low: 22.41,
      pressure: 1017.16,
      sea_level: 1017.16,
      temp: 22.91,
    },
  ],
  '2019-07-26': [
    {
      date: '2019-07-26 18:00:00',
      description: 'broken clouds',
      grnd_level: 1006.19,
      high: 24.64,
      humidity: 49,
      low: 23.98,
      pressure: 1017.03,
      sea_level: 1017.03,
      temp: 24.64,
    },
    {
      date: '2019-07-26 21:00:00',
      description: 'overcast clouds',
      grnd_level: 1006.34,
      high: 22.91,
      humidity: 55,
      low: 22.41,
      pressure: 1017.16,
      sea_level: 1017.16,
      temp: 22.91,
    },
  ],
}

我也尝试过

    return averages.concat({ date: Object.keys(forecasts)[idx], high, low, desc })

收到“平均值”为只读且无法更改的错误

    const oldAvgs = averages
    averages = [...oldAvgs, { date: Object.keys(forecasts)[idx], high, low, desc }]

    return averages

有效,但是就像我说的那样,它正在改变数组

    return averages.push({ date: Object.keys(forecasts)[idx], high, low, desc })

2 个答案:

答案 0 :(得分:1)

您需要返回映射的对象

function getForecastAverages(forecasts) {
  const dailyForecasts = Object.values(forecasts);
  const dailyForecastKeys = Object.keys(forecasts);

  const averages = dailyForecasts.map((hourlyForecasts, idx) => {
    const high = getTempAvg(hourlyForecasts, 'high');
    const low = getTempAvg(hourlyForecasts, 'low');
    const desc = getDescriptionAvg(hourlyForecasts);

    return { date: dailyForecastKeys[idx], high, low, desc };
  });

  return averages;
}

答案 1 :(得分:0)

Javascript数组map方法返回一个新数组,您需要将代码稍作更改,如下所示:

function getForecastAverages(forecasts) {
  const dailyForecasts = Object.values(forecasts);
  const averages = dailyForecasts.map((hourlyForecasts, idx) => {
    const high = getTempAvg(hourlyForecasts, 'high');
    const low = getTempAvg(hourlyForecasts, 'low');
    const desc = getDescriptionAvg(hourlyForecasts);
    const average = { date: Object.keys(forecasts)[idx], high, low, desc };
    return average;
  });

  return averages;
}