Javascript 如何使用Lodash按多个潜在属性过滤对象集合?

Javascript 如何使用Lodash按多个潜在属性过滤对象集合?,javascript,lodash,Javascript,Lodash,我正在构建一个简单的过滤用户界面。我想使用逻辑AND筛选对象集合,其中对象的匹配取决于任意键集中每个对象的多个潜在值。要筛选的对象如下所示: collection = [ { 'Kind': 'Instrument', 'Color': 'Orange', 'Shape': 'Square', 'Name': 'Foobar', }, ... ] filter = { 'Color': ['Red', 'Orange', 'Yellow'],

我正在构建一个简单的过滤用户界面。我想使用逻辑AND筛选对象集合,其中对象的匹配取决于任意键集中每个对象的多个潜在值。要筛选的对象如下所示:

collection = [
  {
    'Kind': 'Instrument',
    'Color': 'Orange',
    'Shape': 'Square',
    'Name': 'Foobar',
  },
  ...
]
filter = {
  'Color': ['Red', 'Orange', 'Yellow'],
  'Shape': ['Circle']
}
用户的点击过滤结果如下所示:

collection = [
  {
    'Kind': 'Instrument',
    'Color': 'Orange',
    'Shape': 'Square',
    'Name': 'Foobar',
  },
  ...
]
filter = {
  'Color': ['Red', 'Orange', 'Yellow'],
  'Shape': ['Circle']
}
在本例中,我希望将集合筛选到以下所有对象:

  • 颜色是红色、橙色或黄色
  • 形状是圆的
filter
对象具有任意数量的键,因此我无法轻松编写如下手动筛选函数:

results = _.filter(collection, item => {
  return _.includes(['Red', 'Orange', 'Yellow'], item['Color']) && _.includes(['Circle'], item['Shape'])
})
使用Lodash实现这一目标的最清洁方式是什么?我是否需要为我的
过滤器中的
集合
中的每个项目在
过滤器
中循环每个键,还是有更好的方法

另外,我没有合适的语言来表达我想做的事情。描述这个问题最好的关键词是什么?

你很接近:

const集合=[
//不会出现在输出中。
{
“种类”:“仪器”,
“颜色”:“橙色”,
'形状':'方形',
'Name':'Foobar',
},
//将出现在输出中。
{
“种类”:“仪器”,
“颜色”:“橙色”,
“形状”:“圆”,
'Name':'Foobar',
},
//不会出现在输出中。
{
“种类”:“德普”,
“颜色”:“NoWorky”,
'形状':'哈哈哈',
'Name':'uWin',
}
];
常数过滤器={
“颜色”:[“红色”、“橙色”、“黄色”],
“形状”:[“圆”]
};
const results=\过滤器(集合,(项)=>{
返回链(过滤器)
.keys()
.reduce((当前布尔值,下一个)=>{
log(currentBoolean,next,filter[next],item[next]);
return.isNil(item[next])?currentBoolean:u.includes(filter[next],item[next])¤tBoolean;
},对)
.value();
//这不起作用,因为您试图创建任意键。
//返回包含(filter.Color,item.Color)和包含(filter.Shape,item.Shape));
});
控制台日志(结果)
您非常接近:

const集合=[
//不会出现在输出中。
{
“种类”:“仪器”,
“颜色”:“橙色”,
'形状':'方形',
'Name':'Foobar',
},
//将出现在输出中。
{
“种类”:“仪器”,
“颜色”:“橙色”,
“形状”:“圆”,
'Name':'Foobar',
},
//不会出现在输出中。
{
“种类”:“德普”,
“颜色”:“NoWorky”,
'形状':'哈哈哈',
'Name':'uWin',
}
];
常数过滤器={
“颜色”:[“红色”、“橙色”、“黄色”],
“形状”:[“圆”]
};
const results=\过滤器(集合,(项)=>{
返回链(过滤器)
.keys()
.reduce((当前布尔值,下一个)=>{
log(currentBoolean,next,filter[next],item[next]);
return.isNil(item[next])?currentBoolean:u.includes(filter[next],item[next])¤tBoolean;
},对)
.value();
//这不起作用,因为您试图创建任意键。
//返回包含(filter.Color,item.Color)和包含(filter.Shape,item.Shape));
});
控制台日志(结果)

您可以简化使用

results = _.filter(collection, item => item.Shape==='Circle' && _.includes(['Red', 'Orange', 'Yellow'], item.Color));

通过在此处对
过滤器
对象进行不同的命名可能是避免混淆的一个好主意。

您可以简化使用

results = _.filter(collection, item => item.Shape==='Circle' && _.includes(['Red', 'Orange', 'Yellow'], item.Color));

在这里,通过对
过滤器
对象进行不同的命名来避免混淆可能是一个好主意。

应用一些函数式风格,我会按照您所说的那样做。希望代码足够解释,否则请让我知道,我将尝试澄清一些事情(使用lodashfp会更清楚一些,尽管我不认为您正在使用它)

希望能有帮助

const isValIncluded=item=>(值,键)=>(值,键,null));
const isValid=filters=>item=>each(filters,isValIncluded(item));
const filterCol=coll=>filters=>u.filter(coll,isValid(filters));
常量集合=[{
“种类”:“仪器”,
“颜色”:“橙色”,
'形状':'方形',
'Name':'Foobar',
},
{
“种类”:“仪器”,
“颜色”:“橙色”,
“形状”:“圆”,
'Name':'Foobar',
},
{
“种类”:“XXX”,
“颜色”:“YYY”,
“形状”:“ZZZ”,
'Name':'FFF',
},
{
“种类”:“仪器”,
“颜色”:“红色”,
“形状”:“圆”,
'Name':'Foobar',
}
];
常数过滤器={
“颜色”:[“红色”、“橙色”、“黄色”],
“形状”:[“圆”]
};
日志(filterCol(collection)(filters))

运用一点功能性风格,我会照你说的做。希望代码足够解释,否则请让我知道,我将尝试澄清一些事情(使用lodashfp会更清楚一些,尽管我不认为您正在使用它)

希望能有帮助

const isValIncluded=item=>(值,键)=>(值,键,null));
const isValid=filters=>item=>each(filters,isValIncluded(item));
const filterCol=coll=>filters=>u.filter(coll,isValid(filters));
常量集合=[{
“种类”:“仪器”,
“颜色”:“橙色”,
'形状':'方形',
'Name':'Foobar',
},
{
“种类”:“仪器”,
“颜色”:“橙色”,
“形状”:“圆”,
'Name':'Foobar',
},
{
“种类”:“XXX”,
“颜色”:“YYY”,
“形状”:“ZZZ”,
'Name':'FFF',
},
{
“种类”:“仪器”,
“颜色”:“红色”,
“形状”:“圆”,
'Name':'Foobar',
}
];
常数过滤器={
“颜色”:[“红色”、“橙色”、“黄色”],
“形状”:[“圆”]
};
日志(filterCol(collection)(filters))

这将适用于要筛选的给定属性为类似“doorColor”的字符串或表示给定属性路径的字符串数组的项目列表,例如['town'、'street'、'doorColor',项目上嵌套的值为town.street.doorColor

它还可以过滤多个值,所以您只需要传入一个sub数组