Javascript Lodash:按多个特性过滤嵌套对象
考虑以下示例:Javascript Lodash:按多个特性过滤嵌套对象,javascript,json,lodash,Javascript,Json,Lodash,考虑以下示例: var products = { "Products": [{ "Title": "A", "Categories": [{ "Name": "Type", "Properties": ["Type 1", "Type 2", "Type 3"] }, { "Name": "Market", "Properties": ["Mar
var products = {
"Products": [{
"Title": "A",
"Categories": [{
"Name": "Type",
"Properties": ["Type 1", "Type 2", "Type 3"]
}, {
"Name": "Market",
"Properties": ["Market 1", "Market 2", "Market 3", "Market 4"]
}, {
"Name": "Technology",
"Properties": ["Tech 1", "Tech 2"]
}]
}, {
"Title": "B",
"Categories": [{
"Name": "Type",
"Properties": ["Type 1", "Type 3"]
}, {
"Name": "Market",
"Properties": "Market 1"
}, {
"Name": "Technology",
"Properties": ["Tech 1", "Tech 3"]
}]
}, {
"Title": "C",
"Categories": [{
"Name": "Type",
"Properties": ["Type 1", "Type 2", "Type 3"]
}, {
"Name": "Market",
"Properties": ["Market 2", "Market 3"]
}, {
"Name": "Technology",
"Properties": ["Tech 2", "Tech 3"]
}]
}]
}
我试图通过属性过滤产品,所以考虑我使用一个数组来跟踪我所选的过滤器:
var filters = ['Type 3', 'Tech 1'];
使用这些过滤器,我想返回产品A和产品B
我目前有:
var flattenedArray = _.chain(products).map('Categories').flatten().value();
var result= _.some(flattenedArray , ['Properties', 'Tech 1']);
但是,我一直在研究如何组合属性进行组合搜索。使用\uu.filter()
迭代产品。对于每个产品,使用.flatMap()
组合属性列表,并使用.intersection()
和.size()
查找类别中存在的过滤器数量。将其与过滤器的原始数量进行比较,并返回比较的响应
var产品={“产品”:[{“标题”:“A”,“类别”:[{“名称”:“类型”,“属性”:[“类型1”,“类型2”,“类型3”]},{“名称”:“市场”,“属性”:[“市场1”,“市场2”,“市场3”,“市场4”]},{“名称”:“技术”,“属性”:[“技术1”,“技术2”]}},{“标题”:“B”,“类别”:[{“名称”:“类型”,“属性”:“类型”,“类型1”,“类型3”},{“名称”:“市场”,“财产”:“市场1”},{“名称”:“技术”、“财产”:[“技术1”、“技术3”]},{“名称”:“C”、“类别”:[{“名称”:“类型”、“财产”:[“类型1”、“类型2”、“类型3”]},{“名称”:“市场”、“财产”:[“市场2”、“市场3”]},{“名称”:“技术”、“财产”:[“技术2”、“技术3”]}};
变量过滤器=['Type 3','Tech 1'];
var结果=551;.filter(products.products,函数(product){
return filters.length===(product.Categories)
.flatMap(“属性”)
.交叉口(过滤器)
.size();
});
console.log(结果);
使用.filter()
迭代产品。对于每个产品,使用.flatMap()
组合属性列表,并使用.intersection()
和.size()
查找类别中存在的筛选器数量。将其与原始筛选器数量进行比较,然后返回比较结果
var产品={“产品”:[{“标题”:“A”,“类别”:[{“名称”:“类型”,“属性”:[“类型1”,“类型2”,“类型3”]},{“名称”:“市场”,“属性”:[“市场1”,“市场2”,“市场3”,“市场4”]},{“名称”:“技术”,“属性”:[“技术1”,“技术2”]}},{“标题”:“B”,“类别”:[{“名称”:“类型”,“属性”:“类型”,“类型1”,“类型3”},{“名称”:“市场”房地产“:”市场1“},{”名称“:”技术“,”房地产“:[”技术1“,”技术3“]},{”标题“:”C“,”类别“:[{”名称“:”类型“,”房地产“:”[”类型1“,”类型2“,”类型3“]},{”名称“:”市场“,”房地产“:”,“{”名称“:”技术“,”房地产“:[”技术2“,”技术3“]}]};
变量过滤器=['Type 3','Tech 1'];
var结果=551;.filter(products.products,函数(product){
return filters.length===(product.Categories)
.flatMap(“属性”)
.交叉口(过滤器)
.size();
});
console.log(结果);
如果我正确理解您的问题,此代码可能有助于:
_.filter(
products.Products,
product => _.difference(
filters,
_.chain(product.Categories).map(category => category.Properties).flatten().value()
).length === 0
);
它计算每个产品的所有属性的并集:
_.chain(product.Categories).map(category => category.Properties).flatten().value()
然后,使用\uu0.difference
方法检查它是否包含所有过滤器
数组元素
希望有帮助。如果我正确理解您的问题,此代码可能会有帮助:
_.filter(
products.Products,
product => _.difference(
filters,
_.chain(product.Categories).map(category => category.Properties).flatten().value()
).length === 0
);
它计算每个产品的所有属性的并集:
_.chain(product.Categories).map(category => category.Properties).flatten().value()
然后,使用\uu0.difference
方法检查它是否包含所有过滤器
数组元素
希望能有帮助。另一种奇特的方式
另一种奇特的方式
这适用于要筛选的给定属性为类似“DoorColor”的字符串或表示给定属性路径的字符串数组的项目列表,如['town'、'street'、'DoorColor'],用于嵌套在项目上的值town.street.DoorColor 它还可以过滤多个值,因此您只需要传入一个表示要保留的字符串值的子字符串数组,它将保留具有字符串值的项,该字符串值包含子字符串数组中的任何子字符串 最后一个参数“includes”确保保留这些值,如果将其设置为false,则它将排除这些值,并保留没有在子字符串数组中指定的任何值的值
import { flatMap, path } from 'lodash/fp';
const filteredListForItemsIncludingSubstringsOnAGivenProperty = (items, givenProperty, substrings, including=true) => flatMap((item) =>
substrings.find((substring) => path(givenProperty)(item) && path(givenProperty)(item).includes(substring))
? including
? [item]
: []
: including
? []
: [item])(items);
例如,fLFIISOAGP(联系人,['person','name',['Joh','Pau',Pet'];
结构为{contact,business:null,personal:{name:'John'}的项目
对于最初的问题-这也会起作用-我会在项目列表上重复使用它,使用不同的键过滤多个属性
const firstFilteredResult=FilteredListForItems包括给定属性的子字符串(
产品,产品,,
[“类别”、“0”、“属性”],
[“类型3”];
const secondFilteredResult=FilteredListForItems包括给定属性的子字符串(
FirstFiltereResult,
[“类别”、“2”、“属性”],
[“Tech 1”];
expect(secondFilteredResult[0]['Title']).to.equal(“A”);
期望(secondFilteredResult[1]['Title'])等于(B);
expect(secondFilteredResult.length).to.equal(2);
这将适用于要筛选的给定属性为类似“doorcolor”的字符串或表示给定属性路径的字符串数组的项目列表,例如['town'、'street'、'doorcolor',用于嵌套在项目上的值town.street.doorcolor
它还可以过滤多个值,因此您只需要传入一个表示要保留的字符串值的子字符串数组,它将保留具有字符串值的项,该字符串值包含子字符串数组中的任何子字符串
最后一个参数“includes”确保保留这些值,如果将其设置为false,则它将排除这些值,并保留没有在子字符串数组中指定的任何值的值
import { flatMap, path } from 'lodash/fp';
const filteredListForItemsIncludingSubstringsOnAGivenProperty = (items, givenProperty, substrings, including=true) => flatMap((item) =>
substrings.find((substring) => path(givenProperty)(item) && path(givenProperty)(item).includes(substring))
? including
? [item]
: []
: including
? []
: [item])(items);
例如,fLFIISOAGP(联系人,['person','name'],['Joh','