【问题标题】:How to calculate average rating of an array?如何计算数组的平均评分?
【发布时间】:2020-10-25 08:14:40
【问题描述】:

下面给出了一个数组数据:

    const ratingData = [
        {name: 'St. Marys School', rating:5},
        {name: 'St. Zaviers School', rating:4},
        {name: 'St. Marys School', rating:3},
        {name: 'Rahul English Medium School', rating:2},
        {name: 'St. Francis High School', rating:3},
        {name: 'Rahul English Medium School', rating:1},
        {name: 'St. Francis High School', rating:4},
        {name: 'Mother Marys High School', rating:5}
    ];

在这个数组中,我想计算每个学校数据的平均评分。但问题是重复的条目,例如“St. Mary's School”有 2 个具有不同评级的条目。如何合并为一个并计算其平均评级?我尝试使用 map 函数,但对于每个条目,它都不起作用。

它的 o/p 应该看起来像这样。 (这只是一个例子)

const output = [
     { name: 'St. Marys School', averageRating: 4},
     { name: 'St. Zaviers School', averageRating: 4},
     { name: 'Rahul English Medium School', averageRating: 1.5},
     { name: 'St. Francis High School', averageRating: 3.5},
     { name: 'Mother Marys High School', averageRating: 5}
];

【问题讨论】:

  • 您应该尝试自己编写代码。在doing more research 之后,如果您仍然有问题,请发布您尝试过的内容,并清楚地解释什么不起作用,并提供minimal reproducible example。阅读How to Ask 一个好问题。请务必tour 并阅读this
  • array.reduce() 是你的朋友。
  • 我会分多个步骤执行此操作 - 首先构建 name => ratings 的地图,然后平均评分,然后将其重新构建为所需的输出数组。

标签: javascript arrays average


【解决方案1】:
let ratingData = [
    {name: 'St. Marys School', rating:5},
    {name: 'St. Zaviers School', rating:4},
    {name: 'St. Marys School', rating:3},
    {name: 'Rahul English Medium School', rating:2},
    {name: 'St. Francis High School', rating:3},
    {name: 'Rahul English Medium School', rating:1},
    {name: 'St. Francis High School', rating:4},
    {name: 'Mother Marys High School', rating:5}
];

let sumData = {};

for (let element of ratingData) {
    if (sumData[element.name]) {
        sumData[element.name].sum = sumData[element.name].sum + element.rating;
        sumData[element.name].n++;
    } else {
        sumData[element.name] = {
            sum: element.rating,
            n: 1
        };
    }
}

console.log('sumData: ' + JSON.stringify(sumData));

let averageData = [];

for (let element of Object.keys(sumData)) {
    averageData.push({
        name: element,
        rating: sumData[element].sum / sumData[element].n
    });
}

console.log('averageData: ' + JSON.stringify(averageData));

sumData 将等于

{
    "St. Marys School": {
        "sum": 8,
        "n": 2
    },
    "St. Zaviers School": {
        "sum": 4,
        "n": 1
    },
    "Rahul English Medium School": {
        "sum": 3,
        "n": 2
    },
    "St. Francis High School": {
        "sum": 7,
        "n": 2
    },
    "Mother Marys High School": {
        "sum": 5,
        "n": 1
    }
}

平均数据将等于

[
    {
        "name": "St. Marys School",
        "rating": 4
    },
    {
        "name": "St. Zaviers School",
        "rating": 4
    },
    {
        "name": "Rahul English Medium School",
        "rating": 1.5
    },
    {
        "name": "St. Francis High School",
        "rating": 3.5
    },
    {
        "name": "Mother Marys High School",
        "rating": 5
    }
]

【讨论】:

    【解决方案2】:

    这是一个使用 reduce() 结合 Map 来检测重复条目的示例。

    首先,它将原始数组缩减为 Map,该数组会累积数组中重复条目的评分。

    {
    {'St. Marys School': [5, 3, 1]},
    {'St. Zaviers School': [4]},
    ...
    }
    

    然后我们使用Array.from 将这个Map 转换回一个数组,并将评级数组减少到一个平均值。

    const ratingData = [
        {name: 'St. Marys School', rating:5},
        {name: 'St. Zaviers School', rating:4},
        {name: 'St. Marys School', rating:3},
        {name: 'Rahul English Medium School', rating:2},
        {name: 'St. Francis High School', rating:3},
        {name: 'Rahul English Medium School', rating:1},
        {name: 'St. Francis High School', rating:4},
        {name: 'Mother Marys High School', rating:5},
        {name: 'St. Marys School', rating:1}
        ]
        
    const mapData = ratingData.reduce((acc, {name, rating}) => {
      const match = acc.get(name);
      match ? 
      match.push(rating) :
      acc.set(name, [rating]);
      return acc;
    }, new Map);
    
    const averageArray = Array.from(mapData, ([name, ratings]) => {
      const rating = ratings.reduce((a, r) => (a + r))/ratings.length;
      return { name, rating }
    });
    
    console.log(averageArray);

    【讨论】:

    • 你的“平均”有缺陷。 5, 3, 1 应该平均到 3 但你的代码平均到 2.5 因为它首先平均 5,3 => 4 然后 4,1 => 2.5
    猜你喜欢
    • 2018-01-04
    • 2015-08-27
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 2015-01-30
    相关资源
    最近更新 更多