我正在NodeJS中构建REST API。我正在构建服务器端的分页,排序和过滤。
我有一个简单的filter方法实现。如果该项不包含任何空字符串,则此方法有效。但是,如果项目包含空字符串,则.toString()
方法将失败,因为item[filterBy]
是null
。
无法读取null的属性“ toString”
如果项包含空字符串,我如何更新过滤器功能以简单地返回true来跳过比较操作?
// Apply filter to array of objects
// TODO: Empty strings breaks the filter
items = items.filter(item =>
item[filterBy].toString().trim().toLowerCase().indexOf(filterValue.toLowerCase()) !== -1)
答案 0 :(得分:2)
要跳过包含空字符串的项目,请尝试以下操作:
item[filterBy] && item[filterBy].toString()
因此,您的代码将是:
items = items.filter(item =>
item[filterBy] && item[filterBy].toString().trim().toLowerCase().indexOf(filterValue.toLowerCase()) !== -1)
答案 1 :(得分:2)
也许是这样的:
const filterValue = 'abc'
const filterBy = 'name'
const items = [
{x: 1, name: 'abc'},
{x: 2, name: 'def'},
{x: 3, noname: 'def'},
{x: 4, name: 'ABCDEF'},
]
const newItems = items.filter(item =>
!(filterBy in item) || item[filterBy].toString().trim().toLowerCase().indexOf(filterValue.toLowerCase()) !== -1)
console.log(newItems)
我们在这里所做的只是检查item
是否具有filterBy
属性。
我不太清楚空字符串的问题是什么。如果item[filterBy]
未定义,您很可能会收到该错误。这就是我们在这里检查的内容。
如果您想跳过不具有相关属性的内容,请从!(filterBy in item) || ...
切换到(filterBy in item) && ...
。
答案 2 :(得分:1)
也许:
items = items.filter(
item => item[filterBy] && item[filterBy].toString ?
item[filterBy].toString().trim().toLowerCase().indexOf(filterValue.toLowerCase()) !== -1 :
false
)
答案 3 :(得分:1)
flatMap()
是.map()
和.flat()
的总和。通过直接返回或不返回值,它可以像反向.filter()
一样起作用。有关详细信息,请参见演示。
const items = [{
id: 'a',
pn: 'B',
desc: ''
}, {
id: 'b',
pn: 'c',
desc: 'd'
}, {
id: 'c',
pn: 'k',
desc: null
}, {
id: 'i',
pn: 'k',
desc: 2
},, {
id: 'o',
pn: 'x',
desc: 3
}];
// Utility function that returns a 'friendlier' value
function clean(obj) {
return obj == null ? false : Array.isArray(obj) ? obj : obj.constructor.name.toLowerCase() === "object" ? obj.toString().trim().toLowerCase() : typeof obj === "string" ? obj.toString().trim().toLowerCase() : Number(parseFloat(obj)) === obj ? obj : false;
}
// Filters by a single key and multiple values
let filterKey = clean('desc');
let filterVal = clean(['d', 2, 'f']);
/* It returns each value in a sub-array an empty array will remove
the value. In the final stage it flattens the array of arrays into a normal array
*/
let list = items.flatMap(item => {
return Object.entries(item).flatMap(([key, value]) => filterKey === (clean(key)) && [...filterVal].includes(clean(value)) ? [clean(value)] :[]);
});
console.log(list);
答案 4 :(得分:0)
链接过滤器是正确的,并且不会影响性能。
const filterValue = 'John'
const filterBy = 'name'
const items = [
{id: 1, name: 'John'},
{id: 2, name: 'Doe, John'},
{id: 3, ref: 1},
{id: 4, name: 'No one'},
{id: 5, name: null}
]
let fItems = items.filter(item => item[filterBy])
.filter(item => item[filterBy].toString().trim().toLowerCase()
.indexOf(filterValue.toLowerCase()) !== -1)
console.log(fItems);
更新:修复了代码。