Javascript 按标记筛选对象(对象数组中的数组) 目标
编辑-使问题更加清晰 创建可根据项目的标记缩小搜索结果范围的搜索,并仅返回具有指定标记的项目。 示例:['green']将为我提供所有绿色项目,包括大、中、小项目(因为没有指定大小),['green'、'big']将仅为我提供绿色和大项目 我遇到了一个情景。为了简化事情,我有以下数据Javascript 按标记筛选对象(对象数组中的数组) 目标,javascript,arrays,object,filter,Javascript,Arrays,Object,Filter,编辑-使问题更加清晰 创建可根据项目的标记缩小搜索结果范围的搜索,并仅返回具有指定标记的项目。 示例:['green']将为我提供所有绿色项目,包括大、中、小项目(因为没有指定大小),['green'、'big']将仅为我提供绿色和大项目 我遇到了一个情景。为了简化事情,我有以下数据 items: [ { title: 'prod1', tags: [{ value: 'green' }, { value: 'big' }] }, { title: 'prod2', tags:
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']
如果我选择green
和big
它将输出['green','big']
如果我选择标记绿色
,我应该返回这些结果
{ title: 'prod1', tags: [{ value: 'green' }, { value: 'big' }] },
{ title: 'prod4', tags: [{ value: 'green' }, { value: 'big' }, { value: 'medium' }] },
如果我选择tagsgreen
和medium
我会得到这些结果,因为prod4是唯一一个有绿色和medium标签的产品
{ title: 'prod4', tags: [{ value: 'green' }, { value: 'big' }, { value: 'medium' }] },
如果我选择green
和big
,我应该得到
{ 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']
我似乎不知道如何按标签过滤我的项目
如果我按标记2(['two']
)搜索,我应该会得到一个返回的
filteredItems: [
{title: 'two', desc: 'this is two', tags: [{value: 'mytag'},{value: two}]},
]
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'}]},
]
如果我用两个,common(['two','common']
)搜索,我应该会得到一个返回值
filteredItems: [
{title: 'two', desc: 'this is two', tags: [{value: 'mytag'},{value: two}]},
]
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.text === 'two')
})
编辑完你的问题后
您的示例数据可以按如下方式搜索:
函数搜索(项目、约束){
返回项目。筛选器(项目=>
约束。每个(约束=>
item.tags.some(obj=>obj.value==约束)
)
);
}
常数项=[
{title:'prod1',标记:[{value:'green'},{value:'big'}]},
{title:'prod2',标记:[{value:'blue'},{value:'small'}]},
{title:'prod3',标记:[{value:'yellow'},{value:'medium'},{value:'big'}]},
{title:'prod4',标记:[{value:'green'},{value:'big'},{value:'medium'}]},
];
日志(搜索(项目,[“绿色”,“中等]))代码>多亏了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' }] },
这将只返回具有两个标记(绿色和大)的对象
我必须修改数组并将其转换为object(我的选择将值输出为['green','big']
为此,我采取了以下措施:
let search = ['green', 'big']
search = search.map(searchTag => {
return {value: searchTag}
})
// [{value: 'green'},{value: 'big'}]
如果有一个普通的es6方法,我很乐意看到它。现在这对我来说很有效如果搜索中的约束变量为null,未定义,'',[],下面的代码应该可以完成您想要的如果约束变量是一个字符串,则假设是一个应用于返回项的约束;如果约束是一个数组,则应用所有约束。我尝试以自解释的方式命名变量
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;
} );
}
};
为什么搜索['two','common']
不包括two
对象?这是搜索下拉列表的方式(使用语义ui)列表用字符串数组显示其值..在第一个代码块中,您没有使用字符串文字'two'
,而是使用具有该名称的变量。那么?无论格式如何,在搜索two
时,为什么two
对象不匹配?我没有得到它two
的值是什么?您在哪里定义ine it?是的,这很有效..至少对于我的游乐场测试..然而,我仍在试图找出我原始问题的解决方案,即使用数组进行搜索/过滤。添加了如何将其应用于原始问题。越来越近..而不是“两个”或“普通”,它必须是“两个”和“普通”。我用更多的信息更新了我的问题,可能更清楚。我尝试在.some函数中使用indexOf返回任何值!==-1,并且仅在搜索单个标记时有效。但一旦我添加第二个标记(['tag1','tag2']
)我没有得到任何回报。顺便说一句,非常感谢,我感觉我离目标越来越近了。这取决于:如果您需要所有条件(输入数组中提供的)为一个匹配的真值,那么您需要每个(但是您在问题中的示例更错误:没有同时具有“两个”和“公共”的记录)。另一方面,如果一个匹配至少有一个输入中提供的值就足够了,那么您需要一些
。但是您的示例是[“两个”,“公共”]
应该给出3个结果,而不是2个。如果你能让你的问题更加清晰一致,说明你在那个例子中需要什么,我会相应地更新我的答案。在这里,我更新了问题。我很抱歉。我不是很清楚。