繁体   English   中英

按标记过滤对象(对象数组内部的数组)

[英]Filter object by tag (array inside an array of objects)

目标

编辑-使问题更清晰

要创建一个搜索,该搜索可以根据项目的标签缩小搜索结果,并且仅返回具有指定标签的项目。 示例:['green']将给我所有绿色的项目,包括大,中和小(因为未指定大小),['green','big']仅给我绿色和大的项目。

我遇到了一个场景。 为了简化起见,我有以下数据

items: [
    { title: 'prod1', tags: [{ value: 'green' }, { value: 'big' }] },
    { title: 'prod2', tags: [{ value: 'blue' }, { value: 'small' }] },
    { title: 'prod3', tags: [{ value: 'yellow' }, { value: 'medium' }, { value: 'big' }] },
    { title: 'prod4', tags: [{ value: 'green' }, { value: 'big' }, { value: 'medium' }] },
]

我的搜索字段是一个多选输入,带有预定义标签(例如本网站中的标签字段),该字段的值作为数组输出。 如果我选择green的输出为[“绿色”]如果我选择greenbig它输出[“绿色”,“大”]

如果我选择green标签,我应该得到这些结果

{ title: 'prod1', tags: [{ value: 'green' }, { value: 'big' }] },
{ title: 'prod4', tags: [{ value: 'green' }, { value: 'big' }, { value: 'medium' }] },

如果我选择greenmedium标签,则会得到这些结果,因为prod4是唯一一个具有绿色和中等标签的标签

{ title: 'prod4', tags: [{ value: 'green' }, { value: 'big' }, { value: 'medium' }] },

如果我选择greenbig我应该得到

{ title: 'prod4', tags: [{ value: 'green' }, { value: 'big' }, { value: 'medium' }] },
{ title: 'prod1', tags: [{ value: 'green' }, { value: 'big' }] }

如果未选择任何内容,则输出所有项目


原始问题

I ran into a scenario. To simplify things, i have the following data

items: [
  {title: 'one', desc: 'this is one', tags: [{value: 'mytag'},{value: 'one'}]},
  {title: 'two', desc: 'this is two', tags: [{value: 'mytag'},{value: two}]},
  {title: 'three', desc: 'this is three', tags: [{value: 'mytag'},{value: 'three'},{value: 'common'}]},
  {title: 'four', desc: 'this is four', tags: [{value: 'mytag'},{value: 'four'},{value: 'common'}]},
]

我有一个接受标签的搜索输入元素,并且输入的值是一个数组。 输入的值为['tag','two']我似乎无法弄清楚如何通过标签过滤项目。

如果我通过标签二( ['two'] )搜索,我应该返回

filteredItems: [
   {title: 'two', desc: 'this is two', tags: [{value: 'mytag'},{value: two}]},
]

如果我用两个普通( ['two','common'] )搜索,我应该返回

filteredItems: [
  {title: 'three', desc: 'this is three', tags: [{value: 'mytag'},{value: 'three'},{value: 'common'}]},
  {title: 'four', desc: 'this is four', tags: [{value: 'mytag'},{value: 'four'},{value: 'common'}]},
]

我试着看一些例子,发现一些只过滤顶级项目而不嵌套数组。

谢谢:)顺便说一下使用javascript,可以使用lodash。

我的游乐场JS文件:

const _ = require('lodash')

let items = [
    {
        name: 'hello',
        tags: [
            { value: 1 },
            { value: 2 },
        ]
    },
    {
        name: 'bye',
        tags: [
            { value: 2 },
            { value: 4 },
        ]
    }
]
items.map(item =>{

    let test = _.includes(item.tags, 2)
    console.log(test)
// returns false, false
})

(注意:此答案的第一部分与原始问题相关,在编辑之前)

您需要更深一层。 最终的游乐场代码将一个对象与2进行比较,但应将一个对象属性与2进行比较。

let test = items.filter(item =>{
    return item.tags.some(obj => obj.value === 2)
})

或者,如果要查找的值在另一个属性中:

let test = items.filter(item =>{
    return item.tags.some(obj => obj.text === 'two')
})

编辑完您的问题后

您的示例数据可以这样搜索:

 function search(items, constraints) { return items.filter(item => constraints.every(constraint => item.tags.some(obj => obj.value === constraint) ) ); } const items = [ { title: 'prod1', tags: [{ value: 'green' }, { value: 'big' }] }, { title: 'prod2', tags: [{ value: 'blue' }, { value: 'small' }] }, { title: 'prod3', tags: [{ value: 'yellow' }, { value: 'medium' }, { value: 'big' }] }, { title: 'prod4', tags: [{ value: 'green' }, { value: 'big' }, { value: 'medium' }] }, ]; console.log(search(items, ["green", "medium"])); 

您需要的逻辑是AND和OR逻辑的组合:对于要匹配给定约束的数组元素,对于给定约束中的每个值(AND),它都应具有一些匹配对象(OR)。

感谢martinoss的这篇文章

解:

使用lodash过滤器功能

let filteredItems = _.filter(items, {tags: [{value: 'green'},{value: 'big'}]}
console.log(filteredItems)

// { title: 'prod1', tags: [{ value: 'green' }, { value: 'big' }] },
// { title: 'prod4', tags: [{ value: 'green' }, { value: 'big' }, { value: 'medium' }] },

这将仅返回具有两个标签(绿色和大)的对象。

我确实必须修改数组并将其转换为对象(我的选择将值输出为['green','big']

我做到了以下几点:

let search = ['green', 'big']

search = search.map(searchTag => {
    return {value: searchTag}
})

// [{value: 'green'},{value: 'big'}]

如果有做香草es6的方式,我很想看看..现在这对我有用

如果搜索中的constraints变量为null,undefined,'',[]或未提供,则下面的代码应该完成您想要的操作,然后不进行过滤就返回项目。 如果constraints变量是一个字符串,则假设是一个约束,该约束将应用于返回的项目;如果constraints是一个Array,则将应用所有约束。 我试图以一种自我解释的方式来命名变量。

var search = (items, constraints) => {
    //no constraints supplied, null, undefined, '', or empty array
  if ( !constraints || constraints === '' || (Array.isArray(constraints) && constraints.length === 0) ) {
    return items;
  }

  let match = false;
  let cons = [];

  //constraints is a string with one constraint add it to an array
  if (typeof constraints === 'string') {
    cons.push(constraints);
  }

  //if constraints is an array of constraints 1 or more
  if (Array.isArray(constraints)) {
    cons.concat(constraints);
    return items.filter( (item) => {
      match = true;
      let itemTags = item.tags.map( (tag) => tag.value );
      cons.forEach( (constraint) => {
        if (constraint === '') return;
        match = (itemTags.indexOf(constraint) > -1 && match);
      } );
      return match;
    } );

  }

};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM