最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Filter array with another array with jQuery or JavaScript - Stack Overflow

programmeradmin2浏览0评论

I am trying to filter an array 'arrSOPrecods' with key values from 'outputdata' another array. the first array 'arrSOPrecods' contains records for users to be trained for a specific SOP the second array 'outputdata' contains records for users already trained for specific SOP I will need to filter out the records that exist in outputdata from arrSOprecords. I have tried many different methods such as jQuery filter, JavaScript for loop as well as its own .filter function with little progress but nothing useful. here is example of the data and what the final output should be.

var arrSOPrecords = [
    { User: "Cesar", SOP: "training 1" },
    { User: "Cesar", SOP: "training 2" },
    { User: "Jon", SOP: "training 1" },
    { User: "Jon", SOP: "training 2" },
    { User: "Ana", SOP: "training 1" },
    { User: "Ana", SOP: "training 2" }
];

var outputdata = [
    { User: "Cesar", SOP: "training 1" }, 
    { User: "Cesar", SOP: "training 2" }, 
    { User: "Ana", SOP: "training 1" }, 
    { User: "Jon", SOP: "training 1" }
];

the final output array .

var filtered = [
    { User: "Ana", SOP: "training 2" },
    { User: "Jon", SOP: "training 2" }
];

I am trying to filter an array 'arrSOPrecods' with key values from 'outputdata' another array. the first array 'arrSOPrecods' contains records for users to be trained for a specific SOP the second array 'outputdata' contains records for users already trained for specific SOP I will need to filter out the records that exist in outputdata from arrSOprecords. I have tried many different methods such as jQuery filter, JavaScript for loop as well as its own .filter function with little progress but nothing useful. here is example of the data and what the final output should be.

var arrSOPrecords = [
    { User: "Cesar", SOP: "training 1" },
    { User: "Cesar", SOP: "training 2" },
    { User: "Jon", SOP: "training 1" },
    { User: "Jon", SOP: "training 2" },
    { User: "Ana", SOP: "training 1" },
    { User: "Ana", SOP: "training 2" }
];

var outputdata = [
    { User: "Cesar", SOP: "training 1" }, 
    { User: "Cesar", SOP: "training 2" }, 
    { User: "Ana", SOP: "training 1" }, 
    { User: "Jon", SOP: "training 1" }
];

the final output array .

var filtered = [
    { User: "Ana", SOP: "training 2" },
    { User: "Jon", SOP: "training 2" }
];
Share Improve this question edited Jun 14, 2016 at 14:07 Andreas 21.9k7 gold badges51 silver badges58 bronze badges asked Jun 14, 2016 at 13:58 user3667159user3667159 591 silver badge6 bronze badges
Add a ment  | 

6 Answers 6

Reset to default 4

You could use a hash table for the items, you want to exclude and filter then the records.

var arrSOPrecords = [{ User: "Cesar", SOP: "training 1" }, { User: "Cesar", SOP: "training 2" }, { User: "Jon", SOP: "training 1" }, { User: "Jon", SOP: "training 2" }, { User: "Ana", SOP: "training 1" }, { User: "Ana", SOP: "training 2" }],
    outputdata = [{ User: "Cesar", SOP: "training 1" }, { User: "Cesar", SOP: "training 2" }, { User: "Ana", SOP: "training 1" }, { User: "Jon", SOP: "training 1" }],
    filtered,
    hash = Object.create(null);

outputdata.forEach(function (a) {
    hash[a.User + '|' + a.SOP] = true;
});
filtered = arrSOPrecords.filter(function (a) {
    return !hash[a.User + '|' + a.SOP];
});

console.log(filtered);

Array.prototype.filter() + Array.prototype.some()

var arrSOPrecords = [
    { User: "Cesar", SOP: "training 1" },
    { User: "Cesar", SOP: "training 2" },
    { User: "Jon", SOP: "training 1" },
    { User: "Jon", SOP: "training 2" },
    { User: "Ana", SOP: "training 1" },
    { User: "Ana", SOP: "training 2" }
];

var outputdata = [
    { User: "Cesar", SOP: "training 1" }, 
    { User: "Cesar", SOP: "training 2" }, 
    { User: "Ana", SOP: "training 1" }, 
    { User: "Jon", SOP: "training 1" }
];

var filtered = arrSOPrecords.filter(function(r) {
    return !outputdata.some(function(t) {
        return r.User === t.User && r.SOP === t.SOP;
    });
});

console.log(JSON.stringify(filtered));

You could use map() on both arrays and return string of User + SOP and then use indexOf() to filter

var arrSOPrecords=[{User:"Cesar", SOP:"training 1"},{User:"Cesar", SOP:"training 2"},{User:"Jon", SOP:"training 1"},{User:"Jon", SOP:"training 2"},{User:"Ana", SOP:"training 1"},{User:"Ana", SOP:"training 2"}]; 
var outputdata= [{User:"Cesar", SOP:"training 1"},{User:"Cesar", SOP:"training 2"},{User:"Ana", SOP:"training 1"},{User:"Jon", SOP:"training 1"}]

var a = arrSOPrecords.map(e => e.User+e.SOP);
var b = outputdata.map(e => e.User+e.SOP);

var result = arrSOPrecords.filter(function(e, i) {
  return b.indexOf(a[i]) == -1;
});

console.log(result)

Update: You can actually just use map on second array and then use filter like this

var arrSOPrecords = [{ User: "Cesar", SOP: "training 1" }, { User: "Cesar", SOP: "training 2" }, { User: "Jon", SOP: "training 1" }, { User: "Jon", SOP: "training 2" }, { User: "Ana", SOP: "training 1" }, { User: "Ana", SOP: "training 2" }];
var outputdata = [{ User: "Cesar", SOP: "training 1" }, { User: "Cesar", SOP: "training 2" }, { User: "Ana", SOP: "training 1" }, { User: "Jon", SOP: "training 1" }];

var a = outputdata.map(e => e.User+e.SOP);
var result = arrSOPrecords.filter(function(el) {
  return a.indexOf(el.User+el.SOP) == -1;
})

console.log(result)

you can try filtering the first array with array.some method:

var arrSOPrecords=[{User:"Cesar", SOP:"training 1"},{User:"Cesar", SOP:"training 2"},{User:"Jon", SOP:"training 1"},{User:"Jon", SOP:"training 2"},{User:"Ana", SOP:"training 1"},{User:"Ana", SOP:"training 2"}];
var outputdata= [{User:"Cesar", SOP:"training 1"},{User:"Cesar", SOP:"training 2"},{User:"Ana", SOP:"training 1"},{User:"Jon", SOP:"training 1"}]


var r = arrSOPrecords.filter(x => !outputdata.some(y => _.isEqual(y,x)))

console.log(r)
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>

to pare the objects inside some method I'm using lodash isEqual but you could use something else to test objects.

I like to present generic, reusable solutions for these problems. The following code will list the objects those are present in array that's called upon which are missing in the array that is provided as an argument. We are utilizing two generic methods; Object.prototype.pare() and Array.prototype.diference().

Object.prototype.pare = function(o){
  var ok = Object.keys(this);
  return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};
Array.prototype.difference = function(a) {
  return this.filter(e => !a.some(f => f.pare(e)));
};
var arrSOP = [
    { User: "Cesar", SOP: "training 1" },
    { User: "Cesar", SOP: "training 2" },
    { User: "Jon", SOP: "training 1" },
    { User: "Jon", SOP: "training 2" },
    { User: "Ana", SOP: "training 1" },
    { User: "Ana", SOP: "training 2" }
],
   outData = [
    { User: "Cesar", SOP: "training 1" }, 
    { User: "Cesar", SOP: "training 2" }, 
    { User: "Ana", SOP: "training 1" }, 
    { User: "Jon", SOP: "training 1" }
],
  filtered = arrSOP.difference(outData);
console.log(JSON.stringify(filtered));

Here is simple solution using Array.filter and Array.indexOf functions:

var filtered = [], trained = {};

outputdata.forEach(function(o) {
    trained[o.User] = trained[o.User] || [];
    trained[o.User].push(o.SOP);
});
filtered = arrSOPrecords.filter(function(o) {
    return !trained[o.User] || trained[o.User].indexOf(o.SOP) === -1;
});

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

The output:

[
    {
        "User": "Jon",
        "SOP": "training 2"
    },
    {
        "User": "Ana",
        "SOP": "training 2"
    }
]
发布评论

评论列表(0)

  1. 暂无评论