如何在对象数组中筛选出包含特定元素的子数组?

12

我正在尝试通过标签筛选列表:

const initialState = [
     {id:1 ,name: 'Product A', image: 'pic-001.jpg', tags: ['nature', 'camping', 'outdoor']},
     {id:2 ,name: 'Product B', image: 'pic-002.jpg', tags: ['winter', 'hiking', 'camping', 'snow']},
     {id:3 ,name: 'Product C', image: 'pic-003.jpg', tags: ['vacation', 'family', 'kids', 'river', 'lake', 'fishing']}
   ]

我可以使用mapfilter通过名称筛选列表,但当我尝试按标签列出产品时遇到问题。我是否需要在产品筛选内部使用foreach?还有其他方法吗?


我认为没有其他方法可以做到这一点。您将不得不通过数组进行迭代以满足标签匹配条件。 - kvn
3
你可以在筛选函数中使用array.indexOf。 - James
4个回答

16

这样行吗?

const filter = 'nature';
const filteredResult = initialState.filter((item) => {
    return (item.tags.indexOf(filter) >= 0);
});

为什么不使用 includes - pishpish
@destoryer,includes是什么?它可能是lodash或underscore的一个特性,但我认为它不是原生JS。 - sjahan
尽管IE不支持includes,但它是一个很有用的JavaScript数组方法。 - pishpish
1
很高兴知道这个,我以为它来自一个实用库!不错 :) - sjahan
不知道为什么,但我必须将其转换为字符串才能使其正常工作。否则会出现错误。return (item.tags.toString().indexOf(tag) >= 0);。谢谢大家,很抱歉回复晚了! - Takebo

9
您可以创建一个选择标签的Set,并使用Array#some来检查Set中至少存在一个标签是否在对象的标签列表中:

const initialState = [
     {id:1 ,name: 'Product A', image: 'pic-001.jpg', tags: ['nature', 'camping', 'outdoor']},
     {id:2 ,name: 'Product B', image: 'pic-002.jpg', tags: ['winter', 'hiking', 'camping', 'snow']},
     {id:3 ,name: 'Product C', image: 'pic-003.jpg', tags: ['vacation', 'family', 'kids', 'river', 'lake', 'fishing']}
];

const filterByTags = ['nature', 'family'];

const filterByTagSet = new Set(filterByTags);

const result = initialState.filter((o) => 
  o.tags.some((tag) => filterByTagSet.has(tag))
);

console.log(result);


2
正是我所需要的。 - Steven

1
你可以使用indexOf函数。
var foo = initialState.filter(function(elm){
  return elm.tags.indexOf("camping")>=0
});

1
首先获取所有标签并从初始状态中过滤重复的标签。将该数组保存到uniqueTags中。
然后将uniqueTags与initialState名称进行比较,以创建另一个包含对象及其属性tags和products的productTags数组。
const initialState = [
     {id:1 ,name: 'Product A', image: 'pic-001.jpg', tags: ['nature', 'camping', 'winter', 'outdoor']},
     {id:2 ,name: 'Product B', image: 'pic-002.jpg', tags: ['winter', 'hiking', 'family', 'camping', 'snow']},
     {id:3 ,name: 'Product C', image: 'pic-003.jpg', tags: ['vacation', 'family', 'kids', 'river', 'lake', 'fishing']}
   ]

   let allTags = [];
   initialState.map((t)=>t.tags).forEach((a)=>a.forEach((b)=>allTags.push(b)))
   let uniqueTags = allTags.filter((a,i,arr)=>arr.indexOf(a,i+1)===-1)


   productTags = [];
   uniqueTags.forEach((u)=>{
       initialState.forEach((t)=>{
           if(t.tags.includes(u))
            productTags.push({'tag': u, 'product':t.name});
       })
   })


   console.log(JSON.stringify(productTags));

   /*
   [
    { "tag": "nature", "product": "Product A" }, 
    { "tag": "outdoor", "product": "Product A" }, 
    { "tag": "winter", "product": "Product A" }, 
    { "tag": "winter", "product": "Product B" }, 
    { "tag": "hiking", "product": "Product B" }, 
    { "tag": "camping", "product": "Product A" }, 
    { "tag": "camping", "product": "Product B" }, 
    { "tag": "snow", "product": "Product B" }, 
    { "tag": "vacation", "product": "Product C" }, 
    { "tag": "family", "product": "Product B" }, 
    { "tag": "family", "product": "Product C" }, 
    { "tag": "kids", "product": "Product C" }, 
    { "tag": "river", "product": "Product C" }, 
    { "tag": "lake", "product": "Product C" }, 
    { "tag": "fishing", "product": "Product C" }
] */

(后来编辑)更正:

为了形成正确的对象,我已将代码更改为:

const initialState = [
     {id:1 ,name: 'Product A', image: 'pic-001.jpg', tags: ['nature', 'camping', 'winter', 'outdoor']},
     {id:2 ,name: 'Product B', image: 'pic-002.jpg', tags: ['winter', 'hiking', 'family', 'camping', 'snow']},
     {id:3 ,name: 'Product C', image: 'pic-003.jpg', tags: ['vacation', 'family', 'kids', 'river', 'lake', 'fishing']}
   ]

   let allTags = [];
   initialState.map((t)=>t.tags).forEach((a)=>a.forEach((b)=>allTags.push(b)))
   let uniqueTags = allTags.filter((a,i,arr)=>!arr.includes(a,i+1))


   productTags = [];
   uniqueTags.forEach((u)=>{
       let productName = [];
       initialState.forEach((t)=>{
           if(t.tags.includes(u))
            productName.push(t.name);
       })
       productTags.push({tag:u, products:productName}); 
   })

   console.log(JSON.stringify(productTags));

   /*
    productTags = [
        {"tag":"nature","products":["Product A"]},
        {"tag":"outdoor","products":["Product A"]},
        {"tag":"winter","products":["Product A","Product B"]},
        {"tag":"hiking","products":["Product B"]},
        {"tag":"camping","products":["Product A","Product B"]},
        {"tag":"snow","products":["Product B"]},
        {"tag":"vacation","products":["Product C"]},
        {"tag":"family","products":["Product B","Product C"]},
        {"tag":"kids","products":["Product C"]},
        {"tag":"river","products":["Product C"]},
        {"tag":"lake","products":["Product C"]},
        {"tag":"fishing","products":["Product C"]}
    ] 
    */

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接