admin管理员组文章数量:1394077
I am building a REST API in NodeJS. I am building the server-side pagination, sorting and filtering.
I have a simple implementation of the filter method. This works if the item does not contain any empty strings. However if the item contains an empty string, the .toString()
method fails because item[filterBy]
is null
.
Cannot read property 'toString' of null
How can I update the filter function to simply return true if the item contains an empty string, to skip the parison operations?
// 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)
I am building a REST API in NodeJS. I am building the server-side pagination, sorting and filtering.
I have a simple implementation of the filter method. This works if the item does not contain any empty strings. However if the item contains an empty string, the .toString()
method fails because item[filterBy]
is null
.
Cannot read property 'toString' of null
How can I update the filter function to simply return true if the item contains an empty string, to skip the parison operations?
// 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)
Share
Improve this question
edited Jun 4, 2019 at 19:09
3limin4t0r
21.2k3 gold badges37 silver badges58 bronze badges
asked Jun 4, 2019 at 19:02
pengzpengz
2,4717 gold badges55 silver badges96 bronze badges
5 Answers
Reset to default 2To skip the item contains an empty string, try this:
item[filterBy] && item[filterBy].toString()
So, your code will be:
items = items.filter(item =>
item[filterBy] && item[filterBy].toString().trim().toLowerCase().indexOf(filterValue.toLowerCase()) !== -1)
Perhaps something like this:
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)
All we do here is check if the item
has a filterBy
property.
It's not quite clear to me what the issue is with empty strings. It seems most likely that you would get that error if item[filterBy]
is undefined. That's what we check here.
If instead you want to skip those that don't have the relevant property, switch from !(filterBy in item) || ...
to (filterBy in item) && ...
.
Maybe:
items = items.filter(
item => item[filterBy] && item[filterBy].toString ?
item[filterBy].toString().trim().toLowerCase().indexOf(filterValue.toLowerCase()) !== -1 :
false
)
flatMap()
is .map()
and .flat()
bined. It can act like a reverse .filter()
by directly returning or not returning values. See demo for details.
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);
It is correct to chain filters and it does not affect performance.
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);
Update: fixed the code.
本文标签: Javascript filter array of objects skip empty stringStack Overflow
版权声明:本文标题:Javascript filter array of objects skip empty string - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744753721a2623333.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论