简体   繁体   中英

How to best “dynamically” make javascript have an conditional to find matches based on multiple possible key value pairs? Looking for a solution

How do I most efficiently structure a "conditions" object to find matches within a list of objects (consisting of key value pairs) and add them to a list of "matches?

I have a the following testList that contains multiple objects:

var testList = {
  "A": "SUBA1",
  "B": "SUBB2",
  "C": "SUBC5",
},
{
  "A": "SUBA2",
  "B": "SUBB3",
  "C": "SUBC1",
}
...
]

Right now my matchCondition with one condition is simple focused on one key and value:

var matchCondition = {"key": "A", val:"SUBA1"};

I want to shove any individual object in testList that matches my "matchCondition" into the "matchedList".

var matchedList = [];

So I do this now using "findMatches" function:

function findMatches(matchCondition, testList) {
var matchedList = [];
for(var i = 0; i < testList.length; i++) {
   if(testList[matchCondition[key]] == testList[i][matchCondition[val]]) {
       matchedList.push(testList[i]);
   }
}
return matchedList;
}

My problem is, what if I want to match using multiple conditions something where for example "A" could be equal to "SUBA1" or "SUBA2", AND "B" is "SUBB2", AND "C" is "SUBB5":

Maybe the object could look like this?

var matchCondition = {
  "A": ["SUBA1", "SUBA2"],
  "B": ["SUBB2"],
  "C": ["SUBC5"]
}

I am not sure what is the best way I can update my findMatches function to be more robust... or how do I best structure my "matchCondition" to be able to support multiple key values I want to match?

You can iterate the mach condition object hasOwnProperty() and check its value meets the requirement.

 var testList = [{ "A": "SUBA1", "B": "SUBB2", "C": "SUBC5", }, { "A": "SUBA2", "B": "SUBB3", "C": "SUBC1", }]; var matchCondition = { "A": ["SUBA1", "SUBA2"], "B": ["SUBB2"], "C": ["SUBC5"] } function findMatches(testList, matchCondition) { return testList.filter(function(obj){ for (var key in matchCondition) { if (matchCondition.hasOwnProperty(key) && obj.hasOwnProperty(key)) { if( matchCondition[key].indexOf(obj[key]) == -1){ return false; } }else{ return false; } } return true }); } snippet.log(JSON.stringify(findMatches(testList, matchCondition))) 
 <!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script> 

A good read Javascript iterate object

A proposal with some array methods like Array.prototype.filter() and Array.prototype.every() and Object.keys() .

 var testList = [{ "A": "SUBA1", "B": "SUBB2", "C": "SUBC5", }, { "A": "SUBA2", "B": "SUBB3", "C": "SUBC1", }], matchCondition = { "A": ["SUBA1", "SUBA2"], "B": ["SUBB2"], "C": ["SUBC5"] }; function filter(data, condition) { return data.filter(function (a) { return Object.keys(condition).every(function (k) { return ~condition[k].indexOf(a[k]); }); }); } document.write('<pre>' + JSON.stringify(filter(testList, matchCondition), 0, 4) + '</pre>'); 

It is not clear what you are expecting as a result, but here is a possible ES6 solution; based on your multiple condition matchCondition example.

 'use strict'; var testList = [{ "A": "SUBA1", "B": "SUBB2", "C": "SUBC5", }, { "A": "SUBA2", "B": "SUBB3", "C": "SUBC1", }]; var matchCondition = { "A": ["SUBA1", "SUBA2"], "B": ["SUBB2"], "C": ["SUBC5"] }; var matchedList = []; for (let item of testList) { let x = Object.create(null); for (let key of Object.keys(matchCondition)) { let val = item[key]; if (val) { for (let sub of matchCondition[key]) { if (sub === val) { x[key] = sub; break; } } } } matchedList.push(x); } document.getElementById('out').textContent = JSON.stringify(matchedList, null, 2); console.log(matchedList); 
 <pre id="out"></pre> 

Or similar in ES5

 'use strict'; var testList = [{ "A": "SUBA1", "B": "SUBB2", "C": "SUBC5", }, { "A": "SUBA2", "B": "SUBB3", "C": "SUBC1", }]; var matchCondition = { "A": ["SUBA1", "SUBA2"], "B": ["SUBB2"], "C": ["SUBC5"] }; var matchedList = testList.reduce(function(acc, item) { var x = Object.create(null); Object.keys(matchCondition).forEach(function(key) { var val = item[key]; if (val) { matchCondition[key].some(function(sub) { if (sub === val) { x[key] = sub; return true; } }); } }); acc.push(x); return acc; }, []); document.getElementById('out').textContent = JSON.stringify(matchedList, null, 2); console.log(matchedList); 
 <pre id="out"></pre> 

These are not your only possibilities, but you need to be clearer about your expectations and it would be good to see what you have tried, and where you are having a problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM