Reputation: 969
I am trying to filter out all records that don't contain values from the 5 arrays: ssn, spn, smft, ssl, svtv. The output is not correct because it only works in cases where the lists contain 1 element. The output array becomes empty when they contain multiple elements. I am trying to get records that don't contain one of the values from each list (OR). I think it doesn't work because it checks if each record doesn't contain all values in each list (AND). Any idea how to fix this?
jsonData
[{"sn": "234234234", "pn": "1014143", "mft": "hello world", "sl": "GG07", "vtv": "Yes"},{"sn": "324234234", "pn": "101423131143", "mft": "hello world 1", "sl": "GG08", "vtv": "Yes"}]
query
ssn: ['T234834U', 'T23423423'],
spn: ['1014114', '21412342'],
smft: ['Sbasdfa', 'asdfaser'],
ssl: ['BB03', 'SFD04'],
svtv: ['Yes']
Code
function getFiltered() {
var query = {
sn: ssn,
pn: spn,
mft: smft,
sl: ssl,
vtv: svtv
}
var filtered = find_in_object(jsonData, query)
}
function find_in_object(my_object, my_criteria) {
return my_object.filter(function(obj) {
return Object.keys(my_criteria).every(function(c) {
return JSON.stringify(obj[c]).indexOf(my_criteria[c]) === -1
})
})
}
Upvotes: 1
Views: 9478
Reputation: 2607
You can use every
for AND
and some
for OR
. In your case you want to go thru the list of keys (so every
for AND
) and then check if the value exists in the search array. indexOf
should do the job:
let jsonData = [
{"sn": "234234234", "pn": "1014143", "mft": "hello world", "sl": "GG07", "vtv": "Yes"},
{"sn": "324234234", "pn": "101423131143", "mft": "hello world 1", "sl": "GG08", "vtv": "Yes"}
]
let query = {
mft: [],
sl: ["GG08"],
vtv: ["No"]
}
console.log(find_in_object(jsonData, query)); //returns one
let query2 = {
sn: ['T234834U', 'T23423423'],
pn: ['1014114', '21412342'],
mft: ['Sbasdfa', 'asdfaser'],
sl: ['BB03', 'SFD04'],
vtv: ['Yes']
}
console.log(find_in_object(jsonData, query2)); //returns none
function find_in_object(my_array, my_criteria) {
return my_array.filter(function(obj) {
return Object.keys(my_criteria).every(function(key) {
return (Array.isArray(my_criteria[key]) &&
(my_criteria[key].some(function(criteria) {
return (typeof obj[key] === 'string' && obj[key].indexOf(criteria) === -1)
})) || my_criteria[key].length === 0);
});
});
}
Edited to cover some edge cases.
Upvotes: 2
Reputation: 7325
Something like this should work
function find_in_object(data, query) {
return data.filter(function(record) {
for(var i in record) {
if(query[i] && query[i].indexOf(record[i]) !== -1) {
return false;
}
}
return true;
});
}
However it is not clear whether you want to match a complete key and value pair, or just a single value regardless of it's key. The above will only work if the key AND the value match.
Upvotes: 0
Reputation: 962
I would turn the json object in an array and then make a simple string comparison to each key.
$(document).ready(function() {
var data = [{"mft": "hello world", "pn": "1014143", "vtv": "Yes", "pn": "T1323F2342", "sl": "GG07"},{"mft": "hello 1", "pn": "234234", "vtv": "Yes", "pn": "T252345234", "sl": "SDF87"}];
filterData(data[0]);
});
function filterData(data) {
var newArray = [];
for (var key in data) {
var value = data[key];
console.log(key, value);
if (key==="ssn" || key==="spn" || key==="smft"|| key==="ssl"|| key==="svtv") {
var object = {key:value};
newArray.push(object)
}
}
return newArray;
}
Upvotes: 0