基于另一个值数组过滤对象数组,返回一个空列表

时间:2022-10-03 20:14:54

I am trying to filter an array of objects using another array of values, but I am getting an empty list. Below is my code

我试图使用另一个值数组过滤对象数组,但我得到一个空列表。以下是我的代码

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}].filter(function(val){
        [1,2,3].forEach(function(id){
           if(id == val.id){
               return true;
           } 
        });
    });

My doubt is

我怀疑是

1)It seems like the callback function of inner forEach doesnt returns the boolean to the parent callback function of filter. Is there a way to achieve this?

1)似乎内部forEach的回调函数不会将boolean返回给filter的父回调函数。有没有办法实现这个目标?

3 个解决方案

#1


0  

Your filter function is returning nothing, so undefined is effectively false, which means it is excluded form the list. Your return statement only returns from the forEach callback.

您的过滤器函数没有返回任何内容,因此undefined实际上是false,这意味着它被排除在列表之外。您的return语句仅从forEach回调返回。

Use .some() instead of .forEach(), and put a return statement before it.

使用.some()而不是.forEach(),并在它之前放置一个return语句。

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}].filter(function(val){
    return [1,2,3].some(function(id){
       if(id == val.id){
           return true;
       } 
    });
});

The .some() method returns true if at least 1 invocation of the callback returns a truthy value. It also halts the iteration as soon as a truthy value is returned.

如果回调的至少1次调用返回truthy值,则.some()方法返回true。一旦返回truthy值,它也会暂停迭代。


FYI, you can shorten it a little by dropping the if statement.

仅供参考,您可以通过删除if语句来缩短它。

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}].filter(function(val){
    return [1,2,3].some(function(id){
       return id == val.id
    });
});

Or even more by using the new arrow function syntax.

或者更多地使用新的箭头函数语法。

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}]
  .filter((val) => [1,2,3].some((id) => id == val.id));

Or since you don't need any complex logic to do the comparison, you can use the ES7 .includes() method, which returns a boolean result based on a strict equality comparison.

或者由于您不需要任何复杂的逻辑来进行比较,您可以使用ES7 .includes()方法,该方法基于严格的相等比较返回布尔结果。

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}]
  .filter(function(val) { return [1,2,3].includes(val.id) });

or

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}]
  .filter((val) => [1,2,3].includes(val.id));

There's a polyfill in the linked docs to patch up older implementations that don't yet have .indcludes().

链接文档中有一个polyfill,用于修补尚未安装.indcludes()的旧实现。

#2


0  

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}].filter(function(val){
        var returnValue = false;
        [1,2,3].forEach(function(id){
           if(id == val.id){
               returnValue = true;
           } 
        });
        return returnValue;
    });

#3


0  

There's a much simple way using Array.filter and Array.indexOf functions:

使用Array.filter和Array.indexOf函数有一个非常简单的方法:

var arr = [{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}];

arr = arr.filter(function(val){
    return [1,2,3].indexOf(val.id) !== -1;
});

console.log(JSON.stringify(arr, 0, 4));

The output:

[
    {
        "id": 1,
        "name": "x1"
    },
    {
        "id": 2,
        "name": "x2"
    },
    {
        "id": 3,
        "name": "x3"
    }
]

#1


0  

Your filter function is returning nothing, so undefined is effectively false, which means it is excluded form the list. Your return statement only returns from the forEach callback.

您的过滤器函数没有返回任何内容,因此undefined实际上是false,这意味着它被排除在列表之外。您的return语句仅从forEach回调返回。

Use .some() instead of .forEach(), and put a return statement before it.

使用.some()而不是.forEach(),并在它之前放置一个return语句。

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}].filter(function(val){
    return [1,2,3].some(function(id){
       if(id == val.id){
           return true;
       } 
    });
});

The .some() method returns true if at least 1 invocation of the callback returns a truthy value. It also halts the iteration as soon as a truthy value is returned.

如果回调的至少1次调用返回truthy值,则.some()方法返回true。一旦返回truthy值,它也会暂停迭代。


FYI, you can shorten it a little by dropping the if statement.

仅供参考,您可以通过删除if语句来缩短它。

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}].filter(function(val){
    return [1,2,3].some(function(id){
       return id == val.id
    });
});

Or even more by using the new arrow function syntax.

或者更多地使用新的箭头函数语法。

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}]
  .filter((val) => [1,2,3].some((id) => id == val.id));

Or since you don't need any complex logic to do the comparison, you can use the ES7 .includes() method, which returns a boolean result based on a strict equality comparison.

或者由于您不需要任何复杂的逻辑来进行比较,您可以使用ES7 .includes()方法,该方法基于严格的相等比较返回布尔结果。

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}]
  .filter(function(val) { return [1,2,3].includes(val.id) });

or

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}]
  .filter((val) => [1,2,3].includes(val.id));

There's a polyfill in the linked docs to patch up older implementations that don't yet have .indcludes().

链接文档中有一个polyfill,用于修补尚未安装.indcludes()的旧实现。

#2


0  

[{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}].filter(function(val){
        var returnValue = false;
        [1,2,3].forEach(function(id){
           if(id == val.id){
               returnValue = true;
           } 
        });
        return returnValue;
    });

#3


0  

There's a much simple way using Array.filter and Array.indexOf functions:

使用Array.filter和Array.indexOf函数有一个非常简单的方法:

var arr = [{'id':1,name:'x1'},{'id':2,name:'x2'},{'id':3,name:'x3'}];

arr = arr.filter(function(val){
    return [1,2,3].indexOf(val.id) !== -1;
});

console.log(JSON.stringify(arr, 0, 4));

The output:

[
    {
        "id": 1,
        "name": "x1"
    },
    {
        "id": 2,
        "name": "x2"
    },
    {
        "id": 3,
        "name": "x3"
    }
]