首页 > 解决方案 > 如何根据嵌套数组中的值检索正确的父对象

问题描述

我有一个具有以下结构的对象数组:

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的属性检查数组中的值。这意味着,我需要检索同时包含值“小”和“黑色”的对象。这应该是它的结果:valueattributes

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);

标签: javascriptarraysloops

解决方案


您只检查value第一个匹配对象的 (当您使用时.some)而不检查其他对象。相反,您想检查value每个对象的每个属性是否是属性列表中的一个属性,方法是使用.includes

const 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(). As.find()将在内部函数返回后停止true

const 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在属性列表上使用,而不是像这样使用对象属性:

const 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 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);


推荐阅读