使用另一个对象数组过滤对象数组

74
这个问题类似于这个问题 Jquery filter array of object with loop,但这次我需要使用对象数组进行过滤。
示例:
我有一个像这样的对象数组:
myArray = [
{
    userid: "100", 
    projectid: "10",
    rowid: "0"
},
{
    userid: "101", 
    projectid: "11",
    rowid: "1"},
{    
    userid: "102", 
    projectid: "12",
    rowid: "2"},
{    
    userid: "103", 
    projectid: "13",
    rowid: "3"
},
{    
    userid: "101", 
    projectid: "10",
    rowid: "4"
}
...]

我想使用如下数组进行过滤:

myFilter = [
{
    userid: "101", 
    projectid: "11"
},
{
    userid: "102", 
    projectid: "12"
},
{
    userid: "103", 
    projectid: "11"
}]

并返回这个结果(在 myFilter 中的 userid 和 projectid 需要与 myArray 中的 userid 和 projectid 匹配):

myArrayFiltered = [
{
    userid: "101", 
    projectid: "11",
    rowid: "1"
},
{
    userid: "102", 
    projectid: "12",
    rowid: "2"
}]

我该如何做到这一点?

11个回答

147

您可以在这里使用一些数组方法-filtersome。 它们可用于所有现代浏览器,并且有用于旧版浏览器的polyfill。

const myArray = [{ userid: "100", projectid: "10", rowid: "0" }, { userid: "101", projectid: "11", rowid: "1"}, { userid: "102", projectid: "12", rowid: "2" }, { userid: "103", projectid: "13", rowid: "3" }, { userid: "101", projectid: "10", rowid: "4" }];
const myFilter = [{ userid: "101", projectid: "11" }, { userid: "102", projectid: "12" }, { userid: "103",  projectid: "11"}];

const myArrayFiltered = myArray.filter((el) => {
  return myFilter.some((f) => {
    return f.userid === el.userid && f.projectid === el.projectid;
  });
});

console.log(myArrayFiltered);


5
太棒了!比使用 for 循环更好!更加简洁。 - NiallMitch14
1
嗨@Andy,我正在做同样的事情,只是一个条件改变不等于!==但在我的情况下这并不起作用。那么还有其他方法可以使用不等于条件吗? 请查看我的实时示例:https://playcode.io/586682/ - TMA
根据您的喜好,您还可以使语句更加简洁:myArray.filter(el => myFilter.some(f => f.userid === el.userid && f.projectid === el.projectid)) - Ivar
如果您有一个 rowid 的数组,这个代码会如何工作呢?(例如:rowid: ["1", "2"] 并且另一个数组至少匹配其中一个)。我已经在我的项目中使用了上面的代码成功地过滤了 difficulty,因为它只有一个值,但是我有一个 tags 的数组需要过滤。所以,如果我的 array1 包含 array2 中的任何一个 tag,则输出一个新的结果数组? - Anake.me
@Anake.me 你应该提出一个新问题。确保你包含输入/期望输出和一个 [mcve] 的代码。 - Andy

38

根据Andy上面的回答,我认为现在应该将其标记为答案。如果您正在寻找完全相反的行为,请使用every和否定,例如:

const result = masterData.filter(ad => 
             filterData.every(fd => fd.userid !== md.userid));

result 包含 所有 masterData除了 filterData


1
这真是太有帮助了!谢谢! - LeLetter

25

使用Ecma script 6。

const myArrayFiltered = myArray.filter( el => {
  return myfilter.some( f => {
    return f.userid === el.userid && f.projectid === el.projectid;
  });
});

功能:

const filterObjectArray = (arr, filterArr) => (
    arr.filter( el =>
        filterArr.some( f =>
            f.userid === el.userid && f.projectid === el.projectid
        )
    )
);

console.log(filterObjectArray(myArray, myFilter))

示例链接


这部分内容实际上只是之前2年中得票最高的答案的重复。 - Mark Schultheiss

17

基于 @Renato 的回答,但更简短:

const myArray = [{ userid: "100", projectid: "10", rowid: "0" }, ...];
const myFilter = [{ userid: "101", projectid: "11" }, ...];

const data = myArray.filter((arrayEl) =>
  myFilter.some((filterEl) => filterEl.userid === arrayEl.userid && filterEl.projectid === arrayEl.projectid)
);

myFilter.some 表达式检查 myFilter 数组中是否至少有一个元素满足设定的条件 (filterEl.userid === arrayEl.userid && filterEl.projectid === arrayEl.projectid)。

如果有,则返回 truemyArray.filter 会将该条目保留在结果数组中,否则被过滤掉。


14
var filtered = [];

for(var arr in myArray){
   for(var filter in myFilter){
       if(myArray[arr].userid == myFilter[filter].userid && myArray[arr].projectid == myFilter[filter].projectid){
          filtered.push(myArray[arr].userid);
         }
   }
}
console.log(filtered);

6

这段代码将与我的过滤器[ j ]的所有属性匹配,而不仅仅是userid和projectid。

var filtered = myArray.filter(function(i){
    return myFilter.some(function(j){
        return !Object.keys(j).some(function(prop){
            return i[prop] != j[prop];
        });
    });
});

console.log(filtered);

因此您可以使用

myFilter = [
    {
        projectid: "11"
    },
    {
        userid: "101"
    },
    {
        userid: "103",
        projectid: "13",
        rowid: "3"
    }
];

将返回

[ { userid: '101', projectid: '11', rowid: '1' },
{ userid: '103', projectid: '13', rowid: '3' },
{ userid: '101', projectid: '10', rowid: '4' } ]

这意味着所有带有

标签的元素。
(projectid=="11") 
OR (userid=="101") 
OR ( (userid=="103") AND (projectid=="13") AND (rowid=="3") )

5
您需要循环遍历第一个数组,然后在该循环内部再次进行过滤器的循环。
如果userid和projectid相等,则可以将该行添加到筛选后的数组中。
myArray = [{
    userid: "100",
    projectid: "10",
    rowid: "0"
}, {
    userid: "101",
    projectid: "11",
    rowid: "1"
}, {
    userid: "102",
    projectid: "12",
    rowid: "2"
}, {
    userid: "103",
    projectid: "13",
    rowid: "3"
}, {
    userid: "101",
    projectid: "10",
    rowid: "4"
}];
myFilter = [{
    userid: "101",
    projectid: "11"
}, {
    userid: "102",
    projectid: "12"
}, {
    userid: "103",
    projectid: "11"
}];

function filterArray(array, filter) {
    var myArrayFiltered = [];
    for (var i = 0; i < array.length; i++) {
        for (var j = 0; j < filter.length; j++) {
            if (array[i].userid === filter[j].userid && array[i].projectid === filter[j].projectid) {
                myArrayFiltered.push(array[i]);
            }
        }
    }
    return myArrayFiltered;
}
myArrayFiltered = filterArray(myArray, myFilter);
console.log(myArrayFiltered);

JSFIDDLE


3
您可以使用jQuery Map函数,它会返回一个匹配项的数组:
var _filter=function(arr_data,arr_filter){
    return $.map( arr_data, function( n ) {
        for(var f in arr_filter){
            if(arr_filter[f].userid == n.userid && arr_filter[f].projectid == n.projectid){
                return n;
            }
        }
    });
}
var resp = _filter(myArray,myFilter);
console.log(resp);

1
如果您需要对相同的内容进行否定。
const masterData = [
{
    userid: "101",
    projectid: "11",
    rowid: "1"
},
{
    userid: "101",
    projectid: "18",
    rowid: "1"
},
{
    userid: "101",
    projectid: "19",
    rowid: "1"
},{
    userid: "102",
    projectid: "12",
    rowid: "2"
}, {
    userid: "109",
    projectid: "10",
    rowid: "4"
}];
const filterData = [
{
    userid: "101",
    projectid: "11"
},
{
    userid: "102",
    projectid: "12"
},
{
    userid: "109",
    projectid: "10"
}
];




const myArrayFiltered = masterData.filter(array => filterData.every(filter => (!(filter.userid === array.userid && filter.projectid === array.projectid))));

             console.log(myArrayFiltered)

1
如果确实需要这样的过滤器,我建议创建一个字典(对象),其键是属性哈希,定义了匹配项(在本例中为userid和projectid),这样你只需要迭代第一个字典(haystack)来检查键是否在第二个字典(needle)中可用。 希望这有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接