当有多个值时,如何使我的过滤器作为 "and" 而不是 "or" 工作?
How can I make my filter work as an "and" instead of "or" when there are multiple values?
我的过滤器有两个限制。
1:当有多个值时,它作为 'or' 而不是 'and'。
例如
filterArr = {'claim_number': null, 'status': 'Approved', 'patient': 'John Connor', 'service_date': null}
this.rows = [
{ 'claim_number': 1234, 'status': 'Approved', 'patient': 'John Connor', 'service_date': '1/10/2018', etc ...}
{ 'claim_number': 4567, 'status': 'Approved', 'patient': 'James Brown', 'service_date': '3/11/2018', etc ...}
{ 'claim_number': 7890, 'status': 'Approved', 'patient': 'Steven Hawkins', 'service_date': '2/1/2018', etc ...}
目前所有这些项目都会匹配,而只有第一个应该匹配,因为只有第一个同时具有 "status: Approved" 和 "patient: John Connor."
2:第二个限制是我想在 this.rows.
中有部分字符串与完整字符串匹配时触发匹配
例如
filterArr = {'claim_number': 12, 'status': 'Approved', 'patient': null, 'service_date': null}
this.rows = [
{ 'claim_number': 1234, 'status': 'Approved', 'patient': 'John
Connor', 'service_date': '1/10/2018', etc ...}
{ 'claim_number': 4567, 'status': 'Approved', 'patient': 'James
Brown', 'service_date': '3/11/2018', etc ...}
{ 'claim_number': 7890, 'status': 'Approved', 'patient': 'Steven Hawkins', 'service_date': '2/1/2018', etc ...}
同样只有第一个应该匹配,因为它包含正确的 "status" 和 "claim_number."
中的前两位数字
这应该相对简单,因为我在传递特定密钥时它可以正常工作,但现在过滤器是动态的,它似乎无法正常工作。
我附上了一个 jsFiddle 以供参考,但它没有正确执行,因为我在 Angular 项目中使用 Reactive Forms。此外,请仅包含使用 ES5 或 ES6 解决的答案。我不能使用 flatMap() 和其他实验性功能。谢谢你。
看看这是否适合你:
const rows = [ { 'claim_number': '1234', 'status': 'Approved', 'patient': 'John Connor', 'service_date': '1/10/2018'}, { 'claim_number': '4567', 'status': 'Approved', 'patient': 'James Brown', 'service_date': '3/11/2018'}, { 'claim_number': '7890', 'status': 'Approved', 'patient': 'Steven Hawkins', 'service_date': '2/1/2018'} ]
const filtrate = (i, f) => {
const vals = Object.values(f).reduce((r,c) => (!!c ? r.push(c) : 0, r), [])
return vals.every(x => Object.values(i).some(y => y.includes(x)))
}
const filterBy = (arr, f) => arr.filter(x => filtrate(x, f))
console.log(filterBy(rows, {'claim_number': null, 'status': 'Approved', 'patient': 'John Connor', 'service_date': null}))
console.log(filterBy(rows, {'claim_number': '12', 'status': 'Approved', 'patient': null, 'service_date': null}))
想法是首先 clean/sanitize
过滤器对象,一旦您只有干净的值,然后通过 Array.every
& Array.some
& Array.includes
实际进行整个搜索。
另请注意,我将数字转换为字符串,因为如果您要搜索 12
是否属于 1234
等,这似乎是您的意图。
为清楚起见,将相同的代码展开:
const rows = [ { 'claim_number': '1234', 'status': 'Approved', 'patient': 'John Connor', 'service_date': '1/10/2018'}, { 'claim_number': '4567', 'status': 'Approved', 'patient': 'James Brown', 'service_date': '3/11/2018'}, { 'claim_number': '7890', 'status': 'Approved', 'patient': 'Steven Hawkins', 'service_date': '2/1/2018'} ]
const filtrate = (item, filter) => {
const values = Object.values(filter).reduce((accumulator, current) => {
if(!!current)
accumulator.push(current)
return accumulator
}, [])
return values.every(value => {
return Object.values(item).some(itm => itm.includes(value))
})
}
const filterBy = (allRows, filterObject) => {
return allRows.filter(row => filtrate(row, filterObject))
}
console.log(filterBy(rows, {'claim_number': null, 'status': 'Approved', 'patient': 'John Connor', 'service_date': null}))
console.log(filterBy(rows, {'claim_number': '12', 'status': 'Approved', 'patient': null, 'service_date': null}))
这是我最终使用的答案。我发现它是最直接的。
@Input() filters: Array<any>;
allRows: Array<any> = [];
applyFilters() {
this.rows = this.allRows;
this.rows = this.rows.filter(row => {
for (let filter of this.filters) {
const filterVal = this.filtersForm.get(filter.key).value;
const rowVal = row[filter.key];
if (!!filterVal && rowVal.toString().toLowerCase().includes(filterVal.toString().toLowerCase())) {
return true;
}
}
return false;
})
}
我的过滤器有两个限制。
1:当有多个值时,它作为 'or' 而不是 'and'。
例如
filterArr = {'claim_number': null, 'status': 'Approved', 'patient': 'John Connor', 'service_date': null}
this.rows = [
{ 'claim_number': 1234, 'status': 'Approved', 'patient': 'John Connor', 'service_date': '1/10/2018', etc ...}
{ 'claim_number': 4567, 'status': 'Approved', 'patient': 'James Brown', 'service_date': '3/11/2018', etc ...}
{ 'claim_number': 7890, 'status': 'Approved', 'patient': 'Steven Hawkins', 'service_date': '2/1/2018', etc ...}
目前所有这些项目都会匹配,而只有第一个应该匹配,因为只有第一个同时具有 "status: Approved" 和 "patient: John Connor."
2:第二个限制是我想在 this.rows.
中有部分字符串与完整字符串匹配时触发匹配例如
filterArr = {'claim_number': 12, 'status': 'Approved', 'patient': null, 'service_date': null}
this.rows = [
{ 'claim_number': 1234, 'status': 'Approved', 'patient': 'John
Connor', 'service_date': '1/10/2018', etc ...}
{ 'claim_number': 4567, 'status': 'Approved', 'patient': 'James
Brown', 'service_date': '3/11/2018', etc ...}
{ 'claim_number': 7890, 'status': 'Approved', 'patient': 'Steven Hawkins', 'service_date': '2/1/2018', etc ...}
同样只有第一个应该匹配,因为它包含正确的 "status" 和 "claim_number."
中的前两位数字这应该相对简单,因为我在传递特定密钥时它可以正常工作,但现在过滤器是动态的,它似乎无法正常工作。
我附上了一个 jsFiddle 以供参考,但它没有正确执行,因为我在 Angular 项目中使用 Reactive Forms。此外,请仅包含使用 ES5 或 ES6 解决的答案。我不能使用 flatMap() 和其他实验性功能。谢谢你。
看看这是否适合你:
const rows = [ { 'claim_number': '1234', 'status': 'Approved', 'patient': 'John Connor', 'service_date': '1/10/2018'}, { 'claim_number': '4567', 'status': 'Approved', 'patient': 'James Brown', 'service_date': '3/11/2018'}, { 'claim_number': '7890', 'status': 'Approved', 'patient': 'Steven Hawkins', 'service_date': '2/1/2018'} ]
const filtrate = (i, f) => {
const vals = Object.values(f).reduce((r,c) => (!!c ? r.push(c) : 0, r), [])
return vals.every(x => Object.values(i).some(y => y.includes(x)))
}
const filterBy = (arr, f) => arr.filter(x => filtrate(x, f))
console.log(filterBy(rows, {'claim_number': null, 'status': 'Approved', 'patient': 'John Connor', 'service_date': null}))
console.log(filterBy(rows, {'claim_number': '12', 'status': 'Approved', 'patient': null, 'service_date': null}))
想法是首先 clean/sanitize
过滤器对象,一旦您只有干净的值,然后通过 Array.every
& Array.some
& Array.includes
实际进行整个搜索。
另请注意,我将数字转换为字符串,因为如果您要搜索 12
是否属于 1234
等,这似乎是您的意图。
为清楚起见,将相同的代码展开:
const rows = [ { 'claim_number': '1234', 'status': 'Approved', 'patient': 'John Connor', 'service_date': '1/10/2018'}, { 'claim_number': '4567', 'status': 'Approved', 'patient': 'James Brown', 'service_date': '3/11/2018'}, { 'claim_number': '7890', 'status': 'Approved', 'patient': 'Steven Hawkins', 'service_date': '2/1/2018'} ]
const filtrate = (item, filter) => {
const values = Object.values(filter).reduce((accumulator, current) => {
if(!!current)
accumulator.push(current)
return accumulator
}, [])
return values.every(value => {
return Object.values(item).some(itm => itm.includes(value))
})
}
const filterBy = (allRows, filterObject) => {
return allRows.filter(row => filtrate(row, filterObject))
}
console.log(filterBy(rows, {'claim_number': null, 'status': 'Approved', 'patient': 'John Connor', 'service_date': null}))
console.log(filterBy(rows, {'claim_number': '12', 'status': 'Approved', 'patient': null, 'service_date': null}))
这是我最终使用的答案。我发现它是最直接的。
@Input() filters: Array<any>;
allRows: Array<any> = [];
applyFilters() {
this.rows = this.allRows;
this.rows = this.rows.filter(row => {
for (let filter of this.filters) {
const filterVal = this.filtersForm.get(filter.key).value;
const rowVal = row[filter.key];
if (!!filterVal && rowVal.toString().toLowerCase().includes(filterVal.toString().toLowerCase())) {
return true;
}
}
return false;
})
}