我有一个具有以下结构的对象数组:
var items = [
{
itemId: 0,
itemQuantity: 10,
attributes: [
{ type: "Size", value: "Small" },
{ type: "Color", value: "Black" }
]
},
{
itemId: 1,
itemQuantity: 20,
attributes: [
{ type: "Size", value: "Small" },
{ type: "Color", value: "White" }
]
},
{
itemId: 2,
itemQuantity: 30,
attributes: [
{ type: "Size", value: "Medium" },
{ type: "Color", value: "Black" }
]
},
{
itemId: 3,
itemQuantity: 40,
attributes: [
{ type: "Size", value: "Medium" },
{ type: "Color", value: "White" }
]
}
];
我还有一个基本数组,其中包含以下值
let selectedAttributes = ["Small", "Black"];
我的目标是基于嵌套数组(attributes
)中的值获取父级对象。要详细说明,我需要使用嵌套数组(selectedAttributes
)中的value
属性检查attributes
数组中的值。这意味着,我需要检索包含两者值“ Small”和“ Black”的对象。这应该是它的结果:
let result = [
{
itemId: 0,
itemQuantity: 10,
attributes: [
{ type: "Size", value: "Small" },
{ type: "Color", value: "Black" }
]
}
]
下面是我当前的代码。当我处理结果时,我得到了一个空数组
let result = items.filter((item, index) => {
return item.attributes.some(attri => attri.value === selectedAttributes);
});
console.log(result);
答案 0 :(得分:1)
您只检查第一个匹配对象的value
(因为您正在使用.some
),而不检查其他对象。相反,您想使用value
检查每个对象的每个.includes
属性是否是属性列表中的一个属性:
var items = [
{
itemId: 0,
itemQuantity: 10,
attributes: [
{ type: "Size", value: "Small" },
{ type: "Color", value: "Black" },
]
},
{
itemId: 1,
itemQuantity: 20,
attributes: [
{ type: "Size", value: "Small" },
{ type: "Color", value: "White" }
]
},
{
itemId: 2,
itemQuantity: 30,
attributes: [
{ type: "Size", value: "Medium" },
{ type: "Color", value: "Black" }
]
},
{
itemId: 3,
itemQuantity: 40,
attributes: [
{ type: "Size", value: "Medium" },
{ type: "Color", value: "White" }
]
}
];
const selectedAttributes = ["Small", "Black"];
const res = items.filter((item, index) => {
return item.attributes.every(attri => selectedAttributes.includes(attri.value));
});
console.log(res);
如果只需要对象(而不是对象数组),则可以使用.find()
代替filter()
。一旦内部函数返回.find()
,true
就会停止:
var items = [
{
itemId: 0,
itemQuantity: 10,
attributes: [
{ type: "Size", value: "Small" },
{ type: "Color", value: "Black" },
]
},
{
itemId: 1,
itemQuantity: 20,
attributes: [
{ type: "Size", value: "Small" },
{ type: "Color", value: "White" }
]
},
{
itemId: 2,
itemQuantity: 30,
attributes: [
{ type: "Size", value: "Medium" },
{ type: "Color", value: "Black" }
]
},
{
itemId: 3,
itemQuantity: 40,
attributes: [
{ type: "Size", value: "Medium" },
{ type: "Color", value: "White" }
]
}
];
const selectedAttributes = ["Small", "Black"];
const res = items.find((item, index) => {
return item.attributes.every(attri => selectedAttributes.includes(attri.value));
});
console.log(res);
请注意,如果所有属性对象都与提供的列表中的属性匹配,则上述解决方案将起作用。如果要使对象中的属性可以具有其他属性以及属性列表的那些部分,则需要在属性列表上使用.every
,而不要像这样使用对象属性:>
var items = [{
itemId: 0,
itemQuantity: 10,
attrs: [{
type: "Size",
value: "Small"
},
{
type: "Color",
value: "Black"
},
{
type: "John",
value: "Name"
}
]
},
{
itemId: 1,
itemQuantity: 20,
attrs: [{
type: "Size",
value: "Small"
},
{
type: "Color",
value: "White"
}
]
},
{
itemId: 2,
itemQuantity: 30,
attrs: [{
type: "Size",
value: "Medium"
},
{
type: "Color",
value: "Black"
}
]
},
{
itemId: 3,
itemQuantity: 40,
attrs: [{
type: "Size",
value: "Medium"
},
{
type: "Color",
value: "White"
}
]
}
];
const attrs = ["Small", "Black"];
const res = items.filter((item, index) => {
const values = item.attrs.map(o => o.value);
return attrs.every(attri => values.includes(attri));
});
console.log(res);