按多个 属性 值过滤数组
Filtering an array by multiple property values
我有一个数组
var cars = [
{name: "BMW X5", topsales: ["USA", "China", "Russia"], maxspeed: 250, users: ["teenage", "ladies", "mens"]}
{name: "Volkswagen Touareg", topsales: ["USA", "Germany"], maxspeed: 240, users: ["teenage", "mens", "old mens"]}
etc....
]
我正在尝试过滤,假设这样说:
var query = {
topsales: ["USA", "China"],
users: "teenage"
}
function nestedFilter(targetArray, filters) {
var filterKeys = Object.keys(filters);
return targetArray.filter(function (eachObj) {
return filterKeys.every(function (eachKey) {
if (!filters[eachKey].length) {
return true;
}
return filters[eachKey].includes(eachObj[eachKey]);
});
});
};
goodresult = nestedFilter(cars, query);
但是该功能无法正常工作。如果对象在属性中有一个值,那么它过滤,但是如果有几个,我至少需要其中一个来满足搜索,那么它不过滤。能请谁帮忙
我假设您打算实施 OR
功能,因为您说 至少其中一项 。因此,工作代码如下。
但在继续阅读之前,请注意以下备注:
我使用 some
而不是 every
,因为 some
与 or
一样工作并且
every
相当于 and
。这意味着该行将 return true 如果
当前 car
项目至少匹配一个过滤器。
您应该使用 item.includes(filter)
filter.includes(item)
.
您需要检查当前筛选项是否为
数组与否,并据此采取行动。
在这段代码中,我没有处理它并假设 currentCandidate
是一个字符串或原始类型。如果还有其他情况候选项(即car
的一个字段)本身也是一个数组,那么你必须更新代码来处理它。
var cars = [
{name: "BMW X5", topsales: "USA, China, Russia", maxspeed: 250, users: "teenage, ladies, men"},
{name: "Volkswagen Touareg", topsales: "USA, Germany", maxspeed: 240, users: "teenage, men, old men"}
]
var query = {
topsales: ["USA", "China"],
maxspeed: 240
}
function nestedFilter(targetArray, filters) {
const filterKeys = Object.keys(filters);
return targetArray.filter(function (eachObj) {
//using some instead of every to make sure that it works as OR
const result = filterKeys.some(function (eachKey) {
//the current item that we are trying to use in the filter
const currentCandidate = eachObj[eachKey];
//the current item that we are using as a filter
const currentFilterItem = filters[eachKey]
if (Array.isArray(currentFilterItem)) {
if (currentFilterItem.length === 0) {
//no filter, return true
return true
}
//loop on each item in the currentFilterItem
//if any of them matches simply return true (OR)
for (let filterKey in currentFilterItem) {
if (currentCandidate.includes(currentFilterItem[filterKey])) {
return true
}
}
//for loop ended, no match
return false
} else {
//the current filter item is not an array, use it as one item
//return eachObj[eachKey].includes(currentFilterItem)
return currentCandidate === currentFilterItem
}
});
return result;
});
}
goodresult = nestedFilter(cars, query);
console.debug(goodresult)
您可以检查查询是否为数组 and/or 值是否为数组并进行相应检查。
function nestedFilter(data, query) {
const
filters = Object.entries(query);
return data.filter(o => filters.every(([k, v]) => Array.isArray(v)
? Array.isArray(o[k])
? v.some(s => o[k].includes(s))
: v.includes(o[k])
: Array.isArray(o[k])
? o[k].includes(v)
: o[k] === v
));
}
const
cars = [{ name: "BMW X5", topsales: ["USA", "China", "Russia"], maxspeed: 250, users: ["teenage", "ladies", "mens"] }, { name: "Volkswagen Touareg", topsales: ["USA", "Germany"], maxspeed: 240, users: ["teenage", "mens", "old mens"] }],
query = { topsales: ["USA", "China"], users: "teenage" };
console.log(nestedFilter(cars, query));
您可以检查“filterKey”的值是否不是数组,将其设为数组,并检查数组是否具有子数组
function hasSubArray(master, sub) {
return sub.every((i => v => i = master.indexOf(v, i) + 1)(0));
}
function nestedFilter(targetArray, filters) {
var filterKeys = Object.keys(filters);
return targetArray.filter(function (eachObj) {
return filterKeys.every(function (eachKey) {
var subArray = filters[eachKey];
if (!Array.isArray(filters[eachKey])) {
subArray = [filters[eachKey]];
}
return hasSubArray(eachObj[eachKey], subArray);
});
});
}
我有一个数组
var cars = [
{name: "BMW X5", topsales: ["USA", "China", "Russia"], maxspeed: 250, users: ["teenage", "ladies", "mens"]}
{name: "Volkswagen Touareg", topsales: ["USA", "Germany"], maxspeed: 240, users: ["teenage", "mens", "old mens"]}
etc....
]
我正在尝试过滤,假设这样说:
var query = {
topsales: ["USA", "China"],
users: "teenage"
}
function nestedFilter(targetArray, filters) {
var filterKeys = Object.keys(filters);
return targetArray.filter(function (eachObj) {
return filterKeys.every(function (eachKey) {
if (!filters[eachKey].length) {
return true;
}
return filters[eachKey].includes(eachObj[eachKey]);
});
});
};
goodresult = nestedFilter(cars, query);
但是该功能无法正常工作。如果对象在属性中有一个值,那么它过滤,但是如果有几个,我至少需要其中一个来满足搜索,那么它不过滤。能请谁帮忙
我假设您打算实施 OR
功能,因为您说 至少其中一项 。因此,工作代码如下。
但在继续阅读之前,请注意以下备注:
我使用
some
而不是every
,因为some
与or
一样工作并且every
相当于and
。这意味着该行将 return true 如果 当前car
项目至少匹配一个过滤器。您应该使用
item.includes(filter)
filter.includes(item)
.您需要检查当前筛选项是否为 数组与否,并据此采取行动。
在这段代码中,我没有处理它并假设
currentCandidate
是一个字符串或原始类型。如果还有其他情况候选项(即car
的一个字段)本身也是一个数组,那么你必须更新代码来处理它。
var cars = [
{name: "BMW X5", topsales: "USA, China, Russia", maxspeed: 250, users: "teenage, ladies, men"},
{name: "Volkswagen Touareg", topsales: "USA, Germany", maxspeed: 240, users: "teenage, men, old men"}
]
var query = {
topsales: ["USA", "China"],
maxspeed: 240
}
function nestedFilter(targetArray, filters) {
const filterKeys = Object.keys(filters);
return targetArray.filter(function (eachObj) {
//using some instead of every to make sure that it works as OR
const result = filterKeys.some(function (eachKey) {
//the current item that we are trying to use in the filter
const currentCandidate = eachObj[eachKey];
//the current item that we are using as a filter
const currentFilterItem = filters[eachKey]
if (Array.isArray(currentFilterItem)) {
if (currentFilterItem.length === 0) {
//no filter, return true
return true
}
//loop on each item in the currentFilterItem
//if any of them matches simply return true (OR)
for (let filterKey in currentFilterItem) {
if (currentCandidate.includes(currentFilterItem[filterKey])) {
return true
}
}
//for loop ended, no match
return false
} else {
//the current filter item is not an array, use it as one item
//return eachObj[eachKey].includes(currentFilterItem)
return currentCandidate === currentFilterItem
}
});
return result;
});
}
goodresult = nestedFilter(cars, query);
console.debug(goodresult)
您可以检查查询是否为数组 and/or 值是否为数组并进行相应检查。
function nestedFilter(data, query) {
const
filters = Object.entries(query);
return data.filter(o => filters.every(([k, v]) => Array.isArray(v)
? Array.isArray(o[k])
? v.some(s => o[k].includes(s))
: v.includes(o[k])
: Array.isArray(o[k])
? o[k].includes(v)
: o[k] === v
));
}
const
cars = [{ name: "BMW X5", topsales: ["USA", "China", "Russia"], maxspeed: 250, users: ["teenage", "ladies", "mens"] }, { name: "Volkswagen Touareg", topsales: ["USA", "Germany"], maxspeed: 240, users: ["teenage", "mens", "old mens"] }],
query = { topsales: ["USA", "China"], users: "teenage" };
console.log(nestedFilter(cars, query));
您可以检查“filterKey”的值是否不是数组,将其设为数组,并检查数组是否具有子数组
function hasSubArray(master, sub) {
return sub.every((i => v => i = master.indexOf(v, i) + 1)(0));
}
function nestedFilter(targetArray, filters) {
var filterKeys = Object.keys(filters);
return targetArray.filter(function (eachObj) {
return filterKeys.every(function (eachKey) {
var subArray = filters[eachKey];
if (!Array.isArray(filters[eachKey])) {
subArray = [filters[eachKey]];
}
return hasSubArray(eachObj[eachKey], subArray);
});
});
}