2

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
        })
    })
}
6
  • You use every try to use some - developer.mozilla.org/en/docs/Web/JavaScript/Reference/… Commented Mar 31, 2017 at 8:55
  • why the JSON.stringify? Commented Mar 31, 2017 at 8:59
  • @Oskar This "some" doesn't solve my problem. The output is still wrong... Commented Mar 31, 2017 at 9:16
  • You still have to update your question. Right now you have array which you want to check against and keys. From your question it seems like you wanted to have 'OR' on the keys and not on the array. Let me update my answer. Commented Mar 31, 2017 at 9:19
  • @Oskar I want to find all records that do not contain the values from the lists. There should be something like an OR between the elements in the lists. I think right now I have an AND between the elements... Is this clear to you? Commented Mar 31, 2017 at 9:22

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks Oskar. I need the opposite version of your code. So all records that don't contain the elements from query/query2. Can I just replace "!==" with "==="?
@Engo so anything what's not in the array you want to filter it out? It seems like you're looking for a sieve. Let me update the code.
@Engo I updated my answer, so right now the first find_in_object returns one element which doesn't have sl equal to 'GG08'
Hi Oskar, I've tried this with my data, but I still get true as output: i.imgur.com/suYL0XM.png I have no idea why this happens. T13G (query -> pn) is subpart of (jsonData -> pn) but still I get true.
@Engo Updated the code once again, didn't know you want to check if the value contains some entries from the array. I changed equality to contains. In that case you can use some on the criteria array to check if a value contains any value from your criteria array.
|
0

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

Comments

0

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.

1 Comment

I assume I have to replace "query" with "criteria", right?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.