Skip to content

Instantly share code, notes, and snippets.

@ZibanPirate
Last active November 26, 2019 22:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZibanPirate/363e80b98b1528bb2e4d9850e45b36f0 to your computer and use it in GitHub Desktop.
Save ZibanPirate/363e80b98b1528bb2e4d9850e45b36f0 to your computer and use it in GitHub Desktop.
Simple Filter Algo for an array of 10000 object
// Qualifications array:
const myQualifications = ["bike", "driver's license"];
/**
* All companies array in the sample, with their requirements, plus one extra company for complex conditions demo
*
* requirements are either:
* - a string, eg: "PayPal account"
* - an object with "or" array inside. eg: { or: ["apartment", "flat", "house"] }
* - an object with "and" array inside. eg: { and: ["social security number", "work permit"] }
* - a nested combination of all the previews, eg: { and: [ { or: ["apartment", "house"] }, "property insurance" ] }
* - a null, for no condition, eg: null
*/
const companiesList = [
{
name: "A",
requires: {
and: [{ or: ["apartment", "house"] }, "property insurance"]
}
},
{
name: "B",
requires: {
and: [
{ or: ["5 door car", "4 door car"] },
"driver's license",
"car insurance"
]
}
},
{
name: "C",
requires: { and: ["social security number", "work permit"] }
},
{
name: "D",
requires: { or: ["apartment", "flat", "house"] }
},
{
name: "E",
requires: {
and: [
"driver's license",
{ or: ["2 door car", "3 door car", "4 door car", "5 door car"] }
]
}
},
{
name: "F",
requires: {
and: [
{ or: ["scooter", "bike", "motorcycle"] },
"driver's license",
"motorcycle insurance"
]
}
},
{
name: "G",
requires: {
and: ["massage qualification certificate", "liability insurance"]
}
},
{
name: "H",
requires: { or: ["storage place", "garage"] }
},
{
name: "J",
requires: null
},
{
name: "K",
requires: "PayPal account"
},
{
name: "Company with complex requirements",
// ( (a || b) && (c || d) ) || (f && g)
// ^ ^ ^ ^ ^
// | | | | |
// 3 2 4 1 5
requires: {
or /* 1 */: [
{
and /* 2 */: [
{ or /* 3 */: ["a", "b"] },
//
{ or /* 4 */: ["c", "d"] }
]
},
{ and /* 5 */: ["f", "g"] }
]
}
}
];
/**
* Check whether a set of qualifications matches a another set of requirements
* @param {any} requirements Requirements
* @param {string[]} qualifications Qualifications
*/
const matchRequirements = (requirements, qualifications) => {
if (typeof requirements === "string") {
return qualifications.includes(requirements);
} else if (requirements !== null) {
const conditions = requirements.or || requirements.and;
const or = requirements.or !== undefined;
const and = !or;
for (let i = 0; i < conditions.length; i++) {
const condition = conditions[i];
if (matchRequirements(condition, qualifications)) {
if (or) return true;
} else {
if (and) return false;
}
}
return and;
} else return true;
};
/**
*
* @param {object[]} companies List of companies
* @param {string[]} qualifications Qualifications
*/
const filterCompanies = (companies, qualifications) => {
const positive = [];
const negative = [];
for (let i = 0; i < companies.length; i++) {
const company = companies[i];
if (matchRequirements(company.requires, qualifications)) {
positive.push(company);
} else {
negative.push(company);
}
}
return { positive, negative };
};
const { positive, negative } = filterCompanies(companiesList, myQualifications);
console.log("I can work on :");
console.log(positive.map(c => " ✅ - " + c.name).join("\n"));
console.log("\nI can not work on :");
console.log(negative.map(c => " ❌ - " + c.name).join("\n"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment