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

I am trying to filter an array 'arrSOPrecods' with key values from 'outputdata' ano

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"
    }
]

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744792131a4593978.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信