考虑以下示例:
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']);
但我仍然坚持如何将这些属性组合起来进行组合搜索。
答案 0 :(得分:2)
使用_.filter()
来迭代产品。对于每个产品,使用_.flatMap()
合并属性列表,并使用_.intersection()
和_.size()
查找类别中存在的过滤器数量。将其与原始过滤器数量进行比较,并返回比较的响应。
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'];
var result = _.filter(products.Products, function(product) {
return filters.length === _(product.Categories)
.flatMap('Properties')
.intersection(filters)
.size();
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
答案 1 :(得分:0)
如果我理解你的问题,这段代码可能会有所帮助:
_.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()
然后使用filters
方法检查它是否包含所有_.difference
数组元素。
希望它有所帮助。
答案 2 :(得分:0)
var res = _.filter(
products.Products,
_.conforms({'Categories': function(categories) {
return _.chain(categories)
.flatMap('Properties') // flat arrays
.uniq() // remove dublicates
.keyBy() // transform to objects with Properties keys
.at(filters) // get objects values by filters
.compact() // remove undefineds
.size() // get size
.eq(filters.length) // compare to filters size
.value();
}
}))
答案 3 :(得分:0)
这将适用于要过滤给定属性的项目列表,该属性是“ doorColour”之类的字符串,还是表示给定属性路径的字符串数组,例如[“ town”,“ street”,“ doorColour” ']表示嵌套在项上的值为town.street.doorColour。
它还可以过滤多个值,因此您只需要传入表示要保留的字符串值的子字符串数组即可,它将保留具有字符串值的项目,该字符串值包含在substrings数组中的任何子字符串。
如果将其设置为false,则最终参数'includes'可确保保留这些值,它将排除这些值并保留不具有您在子字符串数组中指定的任何值的
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']); 的结构项为{联系人,业务:空,个人:{name:'John'}}。
对于最初的问题-这也将起作用-我将在一系列项目中反复使用此代码,以使用不同的键进行过滤,以对多个属性进行过滤。
const firstFilteredResult = filteredListForItemsIncludingSubstringsOnAGivenProperty(
products.Products,
["Categories", "0", "Properties"],
["Type 3"]);
const secondFilteredResult = filteredListForItemsIncludingSubstringsOnAGivenProperty(
firstFilteredResult,
["Categories", "2", "Properties"],
["Tech 1"]);
expect(secondFilteredResult[0]['Title']).to.equal( "A");
expect(secondFilteredResult[1]['Title']).to.equal( "B");
expect(secondFilteredResult.length).to.equal(2);