基于多值对象过滤javascript对象数组
Posted
技术标签:
【中文标题】基于多值对象过滤javascript对象数组【英文标题】:Filter javascript objects array based on a multivalue object 【发布时间】:2020-07-04 15:49:53 【问题描述】:需要根据具有多个值组成数组的过滤器对象来过滤数组
var vendors = [
vendor_name: "John",
region: ["APAC", "UKDE"],
scanned_status: "Yes",
channel: ["FILE", "API"],
pii_attributes: ["A", "B"]
,
vendor_name: "Onir",
region: ["APAC", "LATAM"],
scanned_status: "No",
channel: ["FILE"],
pii_attributes: ["A", "C"]
,
vendor_name: "Suresh",
region: ["UKDE", "NA"],
scanned_status: "Yes",
channel: ["API"],
pii_attributes: ["C", "B"]
];
var filterCriteria =
region: ["APAC", "LATAM"], // 'APAC', 'LATAM', 'NA', 'UKDE'
channel: ["API"], // 'API', 'FILE'
attributes: ["A", "B"],
scan_status: "Yes" // 'Yes', 'No', 'All'
;
let filtered_vendors = [];
var result = vendors.filter((el, index, arr) =>
if (
filterCriteria["region"].includes(el["region"]) &&
filterCriteria["channel"].includes(el["channel"]) &&
filterCriteria["attributes"].includes(el["pii_attributes"])
)
filtered_vendors.push(el);
return true;
return false;
);
console.log(result);
console.log(filtered_vendors);
但我无法在过滤器级别应用多次迭代以包含元素。想知道过滤数组的有效方法。
【问题讨论】:
是否(例如)filterCriteria.region
必须包含来自vendors[].region
的所有 个值或任何 个值?
其中任何一个都可以。
看看'some()' developer.mozilla.org/fr/docs/Web/javascript/Reference/…
【参考方案1】:
我不得不稍微解释一下你的问题。因此,在下面的代码中,我们检查每个过滤器是否过滤器属性值的 所有 元素也在给定的供应商对象属性中(基本上是子集操作)。如果您为每个过滤器指定 any 元素,则需要使用交集操作。
为了实现这一点,我们可以使用reduce
进行迭代,并使用&&
(函数isSupersetOf
)总结各个检查。要将其应用于每个过滤器属性,我们可以对条目集应用相同的技术(函数 isMatch
)。
请注意,我还必须调整属性名称才能使其正常工作。
代码:
var vendors = [
vendor_name: "John",
region: ["APAC", "UKDE"],
scanned_status: "Yes",
channel: ["FILE", "API"],
pii_attributes: ["A", "B"]
,
vendor_name: "Onir",
region: ["APAC", "LATAM"],
scanned_status: "No",
channel: ["FILE"],
pii_attributes: ["A", "C"]
,
vendor_name: "Suresh",
region: ["UKDE", "NA"],
scanned_status: "Yes",
channel: ["API"],
pii_attributes: ["C", "B"]
,
// Add a match for illustration
vendor_name: "Denep",
region: ["APAC", "LATAM", "NA"],
scanned_status: ["Yes"],
channel: ["API"],
pii_attributes: ["A", "B", "C"]
];
const filterCriteria =
region: ["APAC", "LATAM"], // 'APAC', 'LATAM', 'NA', 'UKDE'
channel: ["API"], // 'API', 'FILE'
pii_attributes: ["A", "B"],
scanned_status: ["Yes"] // 'Yes', 'No', 'All'
;
const isSupersetOf = (subset, superset) =>
subset.reduce((result, next) => result && superset.includes(next), true);
const isMatch = (filter, element) =>
Object.entries(filter)
.reduce((result, [property, values]) => result && isSupersetOf(values, element[property] || []), true)
const filteredVendors = vendors.filter((el, index, arr) =>
isMatch(filterCriteria, el))
console.log(filteredVendors);
【讨论】:
【参考方案2】:您也可以通过对filterCriteria
使用相同的键来采取动态方法。
此方法检查过滤器值是否为数组并迭代值并检查包含。
如果没有数组,则直接比较值。
var vendors = [ vendor_name: "John", region: ["APAC", "UKDE"], scanned_status: "Yes", channel: ["FILE", "API"], pii_attributes: ["A", "B"] , vendor_name: "Onir", region: ["APAC", "LATAM"], scanned_status: "No", channel: ["FILE"], pii_attributes: ["A", "C"] , vendor_name: "Suresh", region: ["UKDE", "NA"],
scanned_status: "Yes", channel: ["API"], pii_attributes: ["C", "B"] ],
filterCriteria = region: ["APAC", "LATAM"], channel: ["API"], pii_attributes: ["A", "B"], scanned_status: "Yes" ,
filters = Object.entries(filterCriteria),
result = vendors.filter(o => filters.every(([k, value]) => Array.isArray(value)
? value.some(v => o[k].includes(v)) // change to every if all have to match
: o[k] === value
));
console.log(result);
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
【参考方案3】:var data = [
"id": 1,
"term_id": 5,
"type": "car"
,
"id": 2,
"term_id": 3,
"type": "bike"
,
"id": 3,
"term_id": 6,
"type": "car"
];
var result = data.filter(function(v, i)
return ((v["term_id"] == 5 || v["term_id"] == 6) && v.type == "car");
)
console.log(result)
【讨论】:
这如何回答这个问题?以上是关于基于多值对象过滤javascript对象数组的主要内容,如果未能解决你的问题,请参考以下文章
如何在javascript中将对象数组过滤为另一个对象数组? [关闭]
根据 GPS 位置之间的距离过滤对象数组(javascript)