让array.filter也过滤空值



这是我从一个Web服务中得到的数组。

array = [{category: "Amphibian", common_name: "African Clawed Frog"},{category: "Mammal", common_name: "African Pygmy Hedgehog"},{common_name: "African Spurred Tortoise"}];

现在,当我这样调用这个函数时:

function filterByKey(array, "common_name", "African", "includes") //it works..

所以现在当我想按类别过滤时,比如这样:

function filterByKey(array, "category", "Mammal", "includes") // it doesn't work

但是,由于第三行没有类别列,因此它无法声明以下错误:

未捕获的类型错误:无法读取未定义的属性"toLowerCase">

这是我的功能

function filterByKey(array, key, value, matchOrContain) {
if (matchOrContain == "match") {
var result = array.filter(o => Object.keys(o).some(k => o[key].toLowerCase() === value.toLowerCase()));
} else if (matchOrContain == "includes") {
var result = array.filter(o => Object.keys(o).some(k => o[key].toLowerCase().includes(value
.toLowerCase())));
}
return result;
}

如何避免出现该错误,但同时过滤掉数组?任何帮助都将不胜感激。谢谢

最简单的调整是使用可选的链接,只在密钥存在的情况下调用toLowerCase

const array = [{
category: "Amphibian",
common_name: "African Clawed Frog"
}, {
category: "Mammal",
common_name: "African Pygmy Hedgehog"
}, {
common_name: "African Spurred Tortoise"
}];
console.log(filterByKey(array, "category", "Mammal", "includes"))
function filterByKey(array, key, value, matchOrContain) {
if (matchOrContain == "match") {
var result = array.filter(o => Object.keys(o).some(k => o[key]?.toLowerCase() === value.toLowerCase()));
} else if (matchOrContain == "includes") {
var result = array.filter(o => Object.keys(o).some(k => o[key]?.toLowerCase().includes(value
.toLowerCase())));
}
return result;
}

您也可以通过提前声明回调来显著地DRY代码:

const array = [{
category: "Amphibian",
common_name: "African Clawed Frog"
}, {
category: "Mammal",
common_name: "African Pygmy Hedgehog"
}, {
common_name: "African Spurred Tortoise"
}];
console.log(filterByKey(array, "category", "Mammal", "includes"))
function filterByKey(array, key, value, matchOrContain) {
const lowerValue = value.toLowerCase();
const test = value => (
matchOrContain === 'match'
? value?.toLowerCase().includes(lowerValue)
: value?.toLowerCase() === lowerValue
);
return array.filter(
o => Object.values(o).some(test)
);
}

如果你不能使用可选的链接,那么使用more-vebose方法,并在调用一个方法之前检查该值是否正确:

const array = [{
category: "Amphibian",
common_name: "African Clawed Frog"
}, {
category: "Mammal",
common_name: "African Pygmy Hedgehog"
}, {
common_name: "African Spurred Tortoise"
}];
console.log(filterByKey(array, "category", "Mammal", "includes"))
function filterByKey(array, key, value, matchOrContain) {
const lowerValue = value.toLowerCase();
const test = value => value && (
matchOrContain === 'match'
? value?.toLowerCase().includes(lowerValue)
: value?.toLowerCase() === lowerValue
);
return array.filter(
o => Object.values(o).some(test)
);
}

在您的代码中,在这些部分上,

array.filter(o => Object.keys(o).some(k => o[key].toLowerCase() === value.toLowerCase()));
array.filter(o => Object.keys(o).some(k => o[key].toLowerCase().includes(value
.toLowerCase())));

您已经将o[key]转换为lowerCase,即使它不存在。所以它抛出了错误。

您需要首先检查o[key]的有效性,如果有效,请按以下方式进行比较。

const array = [{
category: "Amphibian",
common_name: "African Clawed Frog"
}, {
category: "Mammal",
common_name: "African Pygmy Hedgehog"
}, {
common_name: "African Spurred Tortoise"
}];

function filterByKey(array, key, value, matchOrContain) {
if (matchOrContain == "match") {
var result = array.filter(o => Object.keys(o).some(k => o[key] && o[key].toLowerCase() === value.toLowerCase()));
} else if (matchOrContain == "includes") {
var result = array.filter(o => Object.keys(o).some(k => o[key] && o[key].toLowerCase().includes(value
.toLowerCase())));
}
return result;
}
console.log(filterByKey(array, "common_name", "African", "includes"));
console.log(filterByKey(array, "category", "Mammal", "includes"));

最新更新