如何通过数组中数组的嵌套子对象对对象进行分组
How to group objects by nested child objects of array in array
我一直遇到这个小问题,一直试图解决这个问题。
我正在调用一个 API 产品,每个产品都有一个键 categories
和一个映射数组的值。尝试按类别对这些进行分类。
这是我来自 API
的示例回复
[
{
"name": "Product one",
"categories": [
{
"id": 1,
"name": "Category One"
}
]
},
{
"name": "Product Two",
"categories": [
{
"id": 1,
"name": "Category One"
},
{
"id": 2,
"name": "Category two"
}
]
}
]
我编写的代码如下:
function groupBy(arr) {
let categories = [];
arr.forEach(el => {
el.categories.forEach(c => {
// Skapa ny kategori om inte redan existerar
if (!categories.includes(c.id)) {
categories.push({
name: c.name,
id: c.id,
products: [el]
});
} else {
// Lägg till produkt i existerande kategori
categories.forEach(_c => {
if (_c.id === c.id) {
_c.products.push(el)
}
})
}
});
});
return categories;
}
groupBy(arr);
我想我有点过分了,想要的结果当然是没有任何重复的类别,产品应该被推到 products[]
.
使用map-reduce
可以做到。
const data = [{"name":"Product one","categories":[{"id":1,"name":"Category One"}]},{"name":"Product Two","categories":[{"id":1,"name":"Category One"},{"id":2,"name":"Category two"}]}];
function categoriesList(list = []) {
return Object.values(
list.reduce((arr, product) => {
product.categories.forEach((cat) => {
if (!arr[cat.id]) arr[cat.id] = { ...cat, products: [] };
arr[cat.id].products.push(product);
});
return arr;
}, {})
);
}
console.log(JSON.stringify(categoriesList(data), null, 4));
.as-console {
min-height: 100% !important;
}
.as-console-row {
color: blue !important;
}
您可以通过首先迭代产品以将其分配给每个类别来执行此操作。为了防止重复,你想使用地图或集合;这里我使用一个 javascript 对象作为地图。一旦你有了它,你可以通过在地图对象
上使用 Object.values() 将它转换成你想要的数组
const groupProductsByCategory = (products) => {
// reduce down each product into a category map
const productsGroupedByCategory = products.reduce((categories, product) => {
// insert the current product into each of the categories it contains
product.categories.forEach(category => {
// if the category exists in the map, we just need to append the current product
if (category.id in categories)
categories[category.id].products.push(product)
else // otherwise, create a new category object with the current product
categories[category.id] = ({ ...category, products: [product] })
})
return categories
}, ({}))
// convert the object into an array of objects
return Object.values(productsGroupedByCategory)
}
我一直遇到这个小问题,一直试图解决这个问题。
我正在调用一个 API 产品,每个产品都有一个键 categories
和一个映射数组的值。尝试按类别对这些进行分类。
这是我来自 API
的示例回复[
{
"name": "Product one",
"categories": [
{
"id": 1,
"name": "Category One"
}
]
},
{
"name": "Product Two",
"categories": [
{
"id": 1,
"name": "Category One"
},
{
"id": 2,
"name": "Category two"
}
]
}
]
我编写的代码如下:
function groupBy(arr) {
let categories = [];
arr.forEach(el => {
el.categories.forEach(c => {
// Skapa ny kategori om inte redan existerar
if (!categories.includes(c.id)) {
categories.push({
name: c.name,
id: c.id,
products: [el]
});
} else {
// Lägg till produkt i existerande kategori
categories.forEach(_c => {
if (_c.id === c.id) {
_c.products.push(el)
}
})
}
});
});
return categories;
}
groupBy(arr);
我想我有点过分了,想要的结果当然是没有任何重复的类别,产品应该被推到 products[]
.
使用map-reduce
可以做到。
const data = [{"name":"Product one","categories":[{"id":1,"name":"Category One"}]},{"name":"Product Two","categories":[{"id":1,"name":"Category One"},{"id":2,"name":"Category two"}]}];
function categoriesList(list = []) {
return Object.values(
list.reduce((arr, product) => {
product.categories.forEach((cat) => {
if (!arr[cat.id]) arr[cat.id] = { ...cat, products: [] };
arr[cat.id].products.push(product);
});
return arr;
}, {})
);
}
console.log(JSON.stringify(categoriesList(data), null, 4));
.as-console {
min-height: 100% !important;
}
.as-console-row {
color: blue !important;
}
您可以通过首先迭代产品以将其分配给每个类别来执行此操作。为了防止重复,你想使用地图或集合;这里我使用一个 javascript 对象作为地图。一旦你有了它,你可以通过在地图对象
上使用 Object.values() 将它转换成你想要的数组const groupProductsByCategory = (products) => {
// reduce down each product into a category map
const productsGroupedByCategory = products.reduce((categories, product) => {
// insert the current product into each of the categories it contains
product.categories.forEach(category => {
// if the category exists in the map, we just need to append the current product
if (category.id in categories)
categories[category.id].products.push(product)
else // otherwise, create a new category object with the current product
categories[category.id] = ({ ...category, products: [product] })
})
return categories
}, ({}))
// convert the object into an array of objects
return Object.values(productsGroupedByCategory)
}