#javascript #arrays #sorting
#javascript #массивы #сортировка
Вопрос:
Напишите функцию с именем sort_by_average_rating
, которая принимает список / массив хранилищ значений ключей в качестве параметра, где каждое хранилище значений ключей имеет ключи ratings
, budget
и box_office
где budget
и box_office
— целые числа, а рейтинги — список целых чисел. Отсортируйте входные данные на основе среднего значения в ratings
.
Я попытался добавить все в цикл for, когда ключ равен ["ratings"]
, затем после этого я усредняю результаты из двух циклов for. Наконец, я использовал отдельную функцию для сортировки всего.
function key(a,b){
for(var i = 0; i < a.length; i ){
tol1 = a[i]["ratings"];
for(var x = 0; x < b.length; x ) {
tol2 = b[x]["ratings"];
}
var average = (tol1/tol2);
}
return average;
}
function key(x,y){
if (x[key] < x[key]) { return -1; }
if (y[key] > y[key]) { return 1; }
return 0;
}
function sort_by_average_rating(b){
b.sort(key)
}
Результат:
[
{'box_office': 12574015, 'budget': 3986053.18, 'ratings': [8, 7, 1]},
{'box_office': 44855251, 'budget': 3301717.62, 'ratings': [7, 1, 1]},
{'box_office': 36625133, 'budget': 8678591, 'ratings': [7, 6, 2, 8]},
{'box_office': 48397691, 'budget': 15916122.88, 'ratings': [7, 3, 8, 8, 6, 8]},
{'box_office': 43344800, 'budget': 4373679.25, 'ratings': [1, 1, 7, 4]}
]
Ожидается:
[
{'box_office': 44855251, 'budget': 3301717.62, 'ratings': [7, 1, 1]},
{'box_office': 43344800, 'budget': 4373679.25, 'ratings': [1, 1, 7, 4]},
{'box_office': 12574015, 'budget': 3986053.18, 'ratings': [8, 7, 1]},
{'box_office': 36625133, 'budget': 8678591.0, 'ratings': [7, 6, 2, 8]},
{'box_office': 48397691, 'budget': 15916122.88, 'ratings': [7, 3, 8, 8, 6, 8]}
]
Комментарии:
1. У тебя их два
function key()
. Используется только второе определение, первое перезаписывается. На самом деле, это только верхушка айсберга…key
внутри функции все еще ссылается на саму функцию.
Ответ №1:
Одним из возможных решений является создание функции, которая возвращает average
из ratings
массива, для этого мы собираемся использовать Array.reduce(). Затем вы можете использовать эту новую функцию со встроенным Array.sort() для получения желаемого результата:
const input = [
{'box_office': 12574015, 'budget': 3986053.18, 'ratings': [8, 7, 1]},
{'box_office': 44855251, 'budget': 3301717.62, 'ratings': [7, 1, 1]},
{'box_office': 36625133, 'budget': 8678591, 'ratings': [7, 6, 2, 8]},
{'box_office': 48397691, 'budget': 15916122.88, 'ratings': [7, 3, 8, 8, 6, 8]},
{'box_office': 43344800, 'budget': 4373679.25, 'ratings': [1, 1, 7, 4]}
];
const getAverage = (arr) =>
{
return (Array.isArray(arr) amp;amp; arr.length > 0) ?
arr.reduce((acc, n) => acc n) / arr.length :
0;
};
input.sort((a, b) => getAverage(a.ratings) - getAverage(b.ratings));
console.log(input);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Чтобы избежать мутации исходных данных, используйте:
let sorted = input.slice().sort((a, b) => getAverage(a.ratings) - getAverage(b.ratings));
Комментарии:
1. Помогло бы передать начальное значение
0
вreduce()
в случае, если нет оценок… хотя тогда результат был быNaN
. 0/0 не определен.2. @PatrickRoberts Спасибо за отзыв, я обновил код.
Ответ №2:
Я предлагаю использовать другой подход (сортировка с помощью карты), взяв средние значения в массиве и другой массив для индексов, отсортировать массив индексов и сопоставить объекты, взяв индексы.
const add = (a, b) => a b;
var array = [{ box_office: 12574015, budget: 3986053.18, ratings: [8, 7, 1] }, { box_office: 44855251, budget: 3301717.62, ratings: [7, 1, 1] }, { box_office: 36625133, budget: 8678591, ratings: [7, 6, 2, 8] }, { box_office: 48397691, budget: 15916122.88, ratings: [7, 3, 8, 8, 6, 8] }, { box_office: 43344800, budget: 4373679.25, ratings: [1, 1, 7, 4] }],
averages = array.map(({ ratings }) => ratings.reduce(add, 0) / ratings.length),
indices = [...averages.keys()].sort((i, j) => averages[i] - averages[j]),
result = indices.map(i => array[i]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ответ №3:
1) вы должны инициализировать свои переменные перед их использованием (например tol1
2) вам следует избегать повторения имен функций (например key
)
3) вы должны называть свои переменные и функции чем-то значимым (например, ‘a’, ‘b’, ‘key’, ‘x’, ‘y’), что ничего не значит.
let movies = [
{'box_office': 12574015, 'budget': 3986053.18, 'ratings': [8, 7, 1]},
{'box_office': 44855251, 'budget': 3301717.62, 'ratings': [7, 1, 1]},
{'box_office': 36625133, 'budget': 8678591, 'ratings': [7, 6, 2, 8]},
{'box_office': 48397691, 'budget': 15916122.88, 'ratings': [7, 3, 8, 8, 6, 8]},
{'box_office': 43344800, 'budget': 4373679.25, 'ratings': [1, 1, 7, 4]}
];
let averageRating = movie =>
movie.ratings.reduce((rating, sum) => rating sum, 0) / movie.ratings.length;
let sortedMovies = movies.sort((movie1, movie2) => averageRating(movie1) - averageRating(movie2));
console.log(sortedMovies);