#javascript #arrays #average
#javascript #массивы #среднее
Вопрос:
Ниже приведены данные массива:
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. Школа Мэри» с разными оценками. Как я могу объединить в один и рассчитать его средний рейтинг? Я пытался использовать 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}
];
Комментарии:
1.
array.reduce()
твой друг здесь.2. Я бы сделал это в несколько этапов — сначала построил карту
name => ratings
, затем усреднил рейтинги, а затем переструктурировал ее в желаемый выходной массив.
Ответ №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()
в сочетании с a Map
для обнаружения повторяющихся записей.
Сначала он уменьшает исходный массив до a Map
, который накапливает рейтинги повторяющихся записей в массиве.
{
{'St. Marys School': [5, 3, 1]},
{'St. Zaviers School': [4]},
...
}
Затем мы преобразуем это Map
обратно в массив, используя Array.from
и уменьшая массив оценок до среднего.
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);
Комментарии:
1. Ваше «усреднение» ошибочно.
5, 3, 1
должно быть в среднем3
, но ваш код усредняет его2.5
, поскольку он сначала усредняет5,3 => 4
, а затем4,1 => 2.5