对象的Javascript筛选器数组跳过空字符串

对象的Javascript筛选器数组跳过空字符串,javascript,filter,Javascript,Filter,我正在NodeJS中构建一个restapi。我正在构建服务器端分页、排序和筛选 我有一个过滤器方法的简单实现。如果项目不包含任何空字符串,则此操作有效。但是,如果项包含空字符串,则.toString()方法将失败,因为项[filterBy]为null 无法读取null的属性“toString” 如果项目包含空字符串,如何更新filter函数以仅返回true,从而跳过比较操作 // Apply filter to array of objects // TODO: Empty string

我正在NodeJS中构建一个restapi。我正在构建服务器端分页、排序和筛选

我有一个过滤器方法的简单实现。如果项目不包含任何空字符串,则此操作有效。但是,如果项包含空字符串,则
.toString()
方法将失败,因为
项[filterBy]
null

无法读取null的属性“toString”

如果项目包含空字符串,如何更新filter函数以仅返回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)
也许:


要跳过包含空字符串的项目,请尝试以下操作:

item[filterBy] && item[filterBy].toString()
因此,您的代码将是:

items = items.filter(item =>
item[filterBy] && item[filterBy].toString().trim().toLowerCase().indexOf(filterValue.toLowerCase()) !== -1)

链式过滤器是正确的,不会影响性能

const filterValue='John'
常量过滤器比='name'
常数项=[
{id:1,名字:'John'},
{id:2,名字:'Doe,John'},
{id:3,ref:1},
{id:4,名字:'没人'},
{id:5,name:null}
]
让fItems=items.filter(item=>item[filterBy])
.filter(item=>item[filterBy].toString().trim().toLowerCase()
.indexOf(filterValue.toLowerCase())!=-1)

控制台日志(fItems)可能是这样的:

const filterValue='abc'
常量过滤器比='name'
常数项=[
{x:1,名称:'abc'},
{x:2,名称:'def'},
{x:3,noname:'def'},
{x:4,名称:'ABCDEF'},
]
const newItems=items.filter(item=>
!(项目中的filterBy)|项目[filterBy].toString().trim().toLowerCase().indexOf(filterValue.toLowerCase())!=-1)
console.log(newItems)
flatMap()
.map()
.flat()
的组合。通过直接返回或不返回值,它可以像反向的
.filter()
。有关详细信息,请参见演示

const项=[{
id:'a',
请注意:‘B’,
描述:“”
}, {
id:'b',
请注意:‘c’,
描述:“d”
}, {
id:'c',
请注意:"k",,
desc:null
}, {
id:'我',
请注意:"k",,
描述:2
},, {
id:'o',
请注意:‘x’,
描述:3
}];
//返回“更友好”值的实用程序函数
功能清洁(obj){
返回obj==null?false:Array.isArray(obj)?obj:obj.constructor.name.toLowerCase()==“object”?obj.toString().trim().toLowerCase():类型obj==“string”?obj.toString().trim().toLowerCase():Number(parseFloat(obj))==obj?obj:false;
}
//按单个键和多个值筛选
让filterKey=clean('desc');
让filterVal=clean(['d',2',f']);
/*它返回空数组将删除的子数组中的每个值
价值。在最后阶段,它将阵列阵列展平为普通阵列
*/
let list=items.flatMap(item=>{
返回Object.entries(item).flatMap(([key,value])=>filterKey==(clean(key))&&&[…filterVal]。包括(clean(value))?[clean(value)]:[];
});

控制台日志(列表)这不是一个过滤器--您正在更改
地图中的数据,而不是对其进行过滤。谢谢,@ScottSauyet。更新了我的答案。如何改进
let list=items.filter(item=>filter.includes(item))
?您可以将ternaries链接起来,并在一行中根据需要解决尽可能多的条件。因此,如果您想返回值以外的内容,它非常简单,您可以明确地删除任何您喜欢的内容,这没有问题。ATM的要求很简单,但显示另一种方法是错误的吗?哦,这显然是一种有趣的技术,是一种将
map
filter
一次性结合起来的好方法。但由于这不是问题的直接答案,如果你要展示这项技术,我认为展示它做一些有用的事情会更好。您的示例更简单地使用
项编写。筛选
。如果更改为
?[items.foo]:[]
,我想这会更清楚。
items = items.filter(item =>
item[filterBy] && item[filterBy].toString().trim().toLowerCase().indexOf(filterValue.toLowerCase()) !== -1)