#javascript #arrays #ecmascript-6 #collections #group-by
#javascript #массивы #ecmascript-6 #Коллекции #группировать по
Вопрос:
У меня есть коллекция элементов, как показано ниже:
[
{ Number: 1, Description: "Example description 1"},
{ Number: 1, Description: "Example description 2"},
{ Number: 2, Description: "Example description 3"},
{ Number: 2, Description: "Example description 4"}
]
Я хотел бы сгруппировать ее по Number
свойству, чтобы получить следующий результат:
[
[
{ Number: 1, Description: "Example description 1"},
{ Number: 1, Description: "Example description 2"}
]
[
{ Number: 2, Description: "Example description 3"},
{ Number: 2, Description: "Example description 4"}
]
]
Следующая функция почти работает для меня:
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
}
но он возвращает объект со свойствами, где каждое свойство является массивом. Это не позволяет мне использовать map
для этого функцию.
Как я могу преодолеть это, чтобы получить возможность использовать массив массивов map
?
Ответ №1:
Вы можете получить значения из объекта.
const
groupBy = function(xs, key) {
return Object.values(xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {}));
},
data = [{ Number: 1, Description: "Example description 1" }, { Number: 1, Description: "Example description 2" }, { Number: 2, Description: "Example description 3" }, { Number: 2, Description: "Example description 4" }];
console.log(groupBy(data, 'Number'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ответ №2:
Лучший способ — использовать reduce
функцию, которая позволяет вам перебирать результат. Затем вы можете создать create array в цикле:
var groupedMap = function(collection, key) {
var result = collection.reduce(
(entryMap, e) => entryMap.set(e[key], [...entryMap.get(e[key])||[], e]),
new Map());
var resultArray = [];
result.forEach(element => {
resultArray.push(element);
});
return resultArray;
}
Примером использования этого метода для вашего случая может быть:
var arrayOfArray = groupedMap(exampleArray, 'Number');
Теперь вы можете вызвать функцию map arrayOfArray
.
Обратите внимание, что это решение не будет работать IE11
, поскольку оно совместимо с ES6
.