Сгруппируйте одинаковые объекты категории
Я пытаюсь сгруппировать необработанные данные из:
items:
[
{
category: "blog",
id : "586ba9f3a36b129f1336ed38",
content : "foo, bar!"
},
{
category: "blog",
id : "586ba9f3a36b129f1336ed3c",
content : "hello, world!"
},
{
category: "music",
id : "586ba9a6dfjb129f1332ldab",
content : "wow, shamwow!"
},
]
в
[
{
category: "blog",
items:
[
{
id : "586ba9f3a36b129f1336ed38",
content : "foo, bar!"
},
{
id : "586ba9f3a36b129f1336ed3c",
content : "hello, world!"
},
]
},
{
category: "music",
items:
[
{
id : "586ba9a6dfjb129f1332ldab",
content : "wow, shamwow!"
}
]
}
]
Такой формат помогает мне печатать одни и те же данные категории вместе во внешнем интерфейсе.
Содержание category
поле динамически, поэтому я не уверен, как сохранить его во временном объекте и отсортировать их, какие-либо мысли?
(Я не могу придумать лучшего заголовка для вопроса, пожалуйста, отредактируйте, если вы получили лучший заголовок.)
3 ответа
Вы можете сделать это с помощью Array#reduce
за один проход:
var items = [{"category":"blog","id":"586ba9f3a36b129f1336ed38","content":"foo, bar!"},{"category":"blog","id":"586ba9f3a36b129f1336ed3c","content":"hello, world!"},{"category":"music","id":"586ba9a6dfjb129f1332ldab","content":"wow, shamwow!"}];
var result = items.reduce(function(r, item) {
var current = r.hash[item.category];
if(!current) {
current = r.hash[item.category] = {
category: item.category,
items: []
};
r.arr.push(current);
}
current.items.push({
id: item.id,
content: item.content
});
return r;
}, { hash: {}, arr: [] }).arr;
console.log(result);
Или ES6 способ использования Map
:
const items = [{"category":"blog","id":"586ba9f3a36b129f1336ed38","content":"foo, bar!"},{"category":"blog","id":"586ba9f3a36b129f1336ed3c","content":"hello, world!"},{"category":"music","id":"586ba9a6dfjb129f1332ldab","content":"wow, shamwow!"}];
const result = [...items.reduce((r, { category, id, content }) => {
r.has(category) || r.set(category, {
category,
items: []
});
r.get(category).items.push({ id, content });
return r;
}, new Map).values()];
console.log(result);
Лично, без каких-либо вспомогательных библиотек, я бы просто сделал это
var step1 = items.reduce((result, {category, id, content}) => {
result[category] = result[category] || [];
result[category].push({id, content});
return result;
}, {});
var result = Object.keys(step1).map(category => ({category, items: step1[category]}));
Какой вавилон превращается в
var step1 = items.reduce(function (result, _ref) {
var category = _ref.category,
id = _ref.id,
content = _ref.content;
result[category] = result[category] || [];
result[category].push({ id: id, content: content });
return result;
}, {});
var result = Object.keys(step1).map(function (category) {
return { category: category, items: step1[category] };
});
Поэтому я только что решил вопрос с помощью следующего кода ( jsfiddle):
// Items
// var items = []
// Create an empty object, used to store the different categories.
var temporaryObject = {}
// Scan for each of the objects in the `items` array.
items.forEach((item) =>
{
// Create a category in the teporary object if the category
// hasn't been created.
if(typeof temporaryObject[item.category] === "undefined")
temporaryObject[item.category] = []
// Push the item to the its category of the `temporaryObject`.
temporaryObject[item.category].push({
id : item.id,
content: item.content
})
})
// Create a empty array used to stores the sorted, grouped items.
var newItems = []
// Scan for each of the category in the `temporaryObject`
for(var category in temporaryObject)
{
// Push the new category in the `newItems` array.
newItems.push({
category: category,
items : []
})
// Get the last category index of the `newItems` array,
// so we can push the related data to the related category.
var lastItem = newItems.length - 1
// Scan for the related category in the `temporaryObject` object.
temporaryObject[category].forEach((item) =>
{
// Push the related data to the related category of the `newItems` array.
newItems[lastItem].items.push(item)
})
}
// Prints the sorted, grouped result.
console.log(newItems)