我想根据多个测试过滤一组对象。对于这个例子,如果键的值不为空,并且一个键的值小于 90,我想过滤一个对象数组。我目前正在使用这样的 for 循环执行此操作:
let filtered = []
for (let i = 0; i < articles.length; i++) {
if (articles[i].title !== null && articles[i].title.length <= 90 &&
articles[i].date !== null &&
articles[i].image !== null &&
articles[i].description !== null &&
articles[i].link !== null) {
filtered.push(articles[i])
}
}
但它非常笨拙,我知道 filter
方法可以实现类似的效果。但我不确定它是否可以使用相同的测试检查多个键及其值,同时检查特定值是否也通过了独立测试。
最佳答案
尝试:
articles.filter(article =>
Object.values(article).every(x => (x !== null))
&& article.title.length <= 90
)
让我们分解一下:
articles.filter(article => ...)
.filter
是接受 callback argument 类型的函数属性,它要求每个项目。本质上,我们是传递给它一个函数——而不是立即执行它,它可以在闲暇时调用它。有点像:
let a = alert;
我们没有调用 alert
函数,我们只是将它保存到一个变量中。在.filter
的情况下,我们将其用作伪变量 - 一个参数。在内部,所有 .filter
正在做的是:
Array.prototype.filter(callbackFunc) {
newArr = [];
for (i=0;i<this.length;i++){
if (callbackFunc(this[i]) === false){ // We're calling `callbackFunc` manually, for each item in the loop.
newArr.push(this[i]);
}
}
return newArr;
}
接下来要解释的是我们正在使用的实际回调函数。它是用 ES6 箭头语法定义的,但它等同于:
articles.filter(function(article){
return Object.values(article).every(x => (x !== null))
&& article.title.length <= 90
})
回调函数第一行,Object.values(article).every(x => (x !== null))
,可以分解为:
let values = Object.values(article); // Get the value of all of the keys in the object
function checkFunction(item){ // Define a helper function
return (x !== null); // Which returns if an item is _not_ null.
}
let result = values.every(checkFunction); // Run `checkFunction` on every item in the array (see below), and ensure it matches _all_ of them.
最后,我们只需要澄清一下every
是什么做。这是函数式 JS 的另一个例子,其中函数接受回调函数作为参数。内部代码如下所示:
Array.prototype.every(callbackFunc) {
for (i=0;i<this.length;i++){
if (callbackFunc(this[i]) === false){ // We're calling `callbackFunc` manually, for each item in the loop.
return false;
}
}
// In JS, returning a value automatically stops execution of the function.
// So this line of code is only reached if `return false` is never met.
return true;
}
和&& article.title.length <= 90
希望应该是不言自明的: while .every
返回一个 bool 值( true
或 false
),一个 true
只会由回调函数返回给 filter
如果第二个条件也满足,即如果 every
返回 true
和 article.title.length <= 90
关于javascript - 使用具有多个测试的 filter 方法过滤对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57444912/