#javascript #arrays #d3.js
#javascript #массивы #d3.js
Вопрос:
У меня есть массив объектов, похожих на
var array = [
{year: 2000, rating: 1, count: 20},
{year: 2000, rating: 1, count: 10},
{year: 2000, rating: 1, count: 5},
{year: 2000, rating: 2, count: 45},
{year: 2000, rating: 2, count: 20},
{year: 2000, rating: 2, count: 17},
{year: 2001, rating: 1, count: 100},
{year: 2001, rating: 1, count: 46},
{year: 2001, rating: 1, count: 30},
{year: 2001, rating: 2, count: 15},
{year: 2001, rating: 2, count: 10},
{year: 2001, rating: 2, count: 5}]
Я хотел бы иметь возможность фильтровать этот массив по верхним n значениям в графе по годам и рейтингу. Я думаю, что slice(0,5) сработал бы, но я новичок в javascript и не могу понять, как перебирать массив на основе года и рейтинга.
Я бы ожидал, что результат для топ-2 будет следующим:
[
{year: 2000, rating: 1, count: 20},
{year: 2000, rating: 1, count: 10},
{year: 2000, rating: 2, count: 45},
{year: 2000, rating: 2, count: 20},
{year: 2001, rating: 1, count: 100},
{year: 2001, rating: 1, count: 46},
{year: 2001, rating: 2, count: 15},
{year: 2001, rating: 2, count: 10}
]
Комментарии:
1. Можете ли вы поделиться своим ожидаемым результатом для предоставленных данных?
2. Конечно! Итак, если бы я хотел получить объекты с 2 верхними значениями для count, я бы ожидал увидеть: var new_array = [ {год: 2000, рейтинг: 1, количество: 20}, {год: 2000, рейтинг: 1, количество: 10}, {год: 2000, рейтинг: 2, количество: 45}, {год: 2000, рейтинг: 2, количество: 20}, {год: 2001, рейтинг: 1, количество: 100}, {год: 2001, рейтинг: 1, количество: 46}, {год: 2001, рейтинг: 2, количество: 15}, {год выпуска: 2001, рейтинг: 2, количество: 10}]
3. Всегда ли входные данные сортируются по
year
иrating
?4. Да, я смог отсортировать массив в соответствующем порядке.
5. И должен ли порядок объектов в выходном массиве соответствовать порядку объектов из исходного массива? например: может
{...... count: 10}
быть раньше{...... count: 15}
в результате?
Ответ №1:
Вы можете сгруппировать по year
и rating
(используя year-rating
ключи), используя .reduce()
и Map
, чтобы у вас был массив объектов, которые указывают количество и индекс, с которым встречается каждый объект:
2000-1: [{count: 20, idx: 0}, {count: 10,idx: 1}, {count: 5, idx: 2}, ...],
2000-2: [{count: 45, idx: 4}, ...],
2001-1: [...],
2001-2: [...]
после того, как у вас есть карта вышеупомянутой структуры, вы можете отсортировать каждый массив значений по количеству в порядке возрастания и использовать .slice(-n)
для получения верхних (последних) n
элементов. Получив верхние элементы, вы можете сопоставить top
массивы значений каждого значения с их фактическими значениями объектов, используя idx
свойство. Однако прежде чем вы это сделаете, вы можете выполнить сортировку по idx
, чтобы сохранить относительный порядок:
const arr = [ {year: 2000, rating: 1, count: 20}, {year: 2000, rating: 1, count: 10}, {year: 2000, rating: 1, count: 5}, {year: 2000, rating: 2, count: 45}, {year: 2000, rating: 2, count: 20}, {year: 2000, rating: 2, count: 17}, {year: 2001, rating: 1, count: 100}, {year: 2001, rating: 1, count: 46}, {year: 2001, rating: 1, count: 30}, {year: 2001, rating: 2, count: 15}, {year: 2001, rating: 2, count: 10}, {year: 2001, rating: 1, count: 5} ];
const n = 2;
const res = Array.from(arr.reduce((acc, {year, rating, count}, idx) => {
const key = `${year}-${rating}`;
const curr = acc.get(key) || [];
return acc.set(key, [...curr, {count, idx}])
}, new Map).values(), group => group.sort((a, b) => a.count - b.count).slice(-n)).flatMap(
top => top.sort((a, b) => a.idx - b.idx).map(({idx}) => arr[idx])
);
console.log(res);