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

时间:2015-06-23 14:19:34

标签: javascript jquery arrays object filter

这个问题类似于这个问题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 个答案:

答案 0 :(得分:17)

您可以在此处使用几种数组方法 - filtersome。它们在所有最近的浏览器中都可用,并且旧版浏览器可以使用填充。

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

DEMO

答案 1 :(得分:4)

你需要遍历你的第一个数组,并在这个循环中,再次在过滤器内循环。

如果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

答案 2 :(得分:4)

使用Ecma脚本6。

x = 1.0f,
y = 0,
z = 0,
w = 1.0f

功能:

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

Link to example

答案 3 :(得分:3)

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);

答案 4 :(得分:3)

针对上述Andy的回答,我认为现在应该将其标记为答案。如果您正在寻找完全相反的行为,请使用every取反,类似这样。

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

result包含all masterData except filterData

答案 5 :(得分:2)

此代码不仅与userid和projectid匹配,还与myFilter [j]的所有属性匹配。

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") )

答案 6 :(得分:2)

你可以使用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);

答案 7 :(得分:0)

如果需要这样的过滤器,我建议创建一个字典(对象),其键是属性的散列,定义匹配(在本例中为userid&amp; projectid),这样你需要迭代第一个字典(haystack)检查第二个dict(针)是否有钥匙。 希望这会有所帮助。

答案 8 :(得分:0)

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

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

const myArrayFiltered = myArray.filter(array => myFilter.some(filter => filter.userid === array.userid && filter.projectid === array.projectid));

答案 9 :(得分:0)

var arr1 = [
    { name:'r', type:"t1" },
    { name:'i', type:"t2" },
    { name:'n', type:"t1" }
];

var arr2 = [
    { name:'r', type:"t1" },
    { name:'i', type:"t2" },
    { name:'n', type:"t3" },
];

let output = arr1.filter(x => !arr2.find(y => (y.name == x.name && y.type == x.type)));

console.log(output);

// inverted

output = arr1.filter(x => !!arr2.find(y => (y.name == x.name && y.type == x.type)));

console.log(output);

答案 10 :(得分:0)

如果你需要同样的否定

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)