Created
January 20, 2022 17:29
-
-
Save nickgrato/dc55cbf6c8fa99d5ea49965bacd26405 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class PriceSpecification { | |
/** | |
* @param {min: Number, max: Number} price | |
*/ | |
constructor(price) { | |
this.min = price.min | |
this.max = price.max | |
} | |
/** | |
* Spec Description | |
* @param {Product} product | |
*/ | |
isSatisfied(product) { | |
const product_price = product.price / 100 | |
return product_price <= this.max && product_price >= this.min | |
} | |
} | |
export class ColorSpecification { | |
/** | |
* @param color: String | |
*/ | |
constructor(color) { | |
this.color = color | |
} | |
/** | |
* Spec Description | |
* @param {Product} product | |
*/ | |
isSatisfied(product) { | |
// check is product have color here.. | |
let colorFound = false | |
// Color is index "0" | |
const colors = product.options[0].values | |
if(colors.indexOf(this.color) !== -1) colorFound = true | |
return colorFound | |
}} | |
/** | |
* 'And' specification example blue 'AND' small will only satifisy, | |
* this is used as a relationship between two specification blocks. | |
*/ | |
export class AndSpecification { | |
/** | |
* @param {Specs} specs | |
*/ | |
constructor(...specs) { | |
this.specs = specs | |
} | |
isSatisfied(product) { | |
return this.specs.every((spec) => spec.isSatisfied(product)) | |
} | |
} | |
/** | |
* 'OR' specification example blue 'OR' white will satifisy, this | |
* is used as a relationship between filter values in a specific specification. | |
*/ | |
export class OrSpecification { | |
/** | |
* @param {Specs} specs | |
*/ | |
constructor(...specs) { | |
this.specs = specs | |
} | |
isSatisfied(product) { | |
return this.specs.some((spec) => spec.isSatisfied(product)) | |
} | |
} | |
export class MegaFilter { | |
/** | |
* @param {Product} products | |
* @param {Spec} spec | |
*/ | |
filter(products, spec) { | |
return products.filter((product) => spec.isSatisfied(product)) | |
} | |
} | |
//********** | |
// USE CASE | |
//********** | |
const filterProducts = () => { | |
// Create Mega Filter | |
const megaFilter = new MegaFilter() | |
// Create Price Specificaiton | |
const priceParams = { min: 0, max: 40} | |
const price_spec = new PriceSpecification(priceParams) | |
// Create Color Specifications | |
const color_spec = ['blue','red'].map((value) => new ColorSpecification(value)) | |
// Group Specs | |
const colorOptions = new OrSpecification(...color_spec) | |
// Note: This will effectively create a filter that finds products that has atlease one of the colors AND | |
// is within the price limitations expressed in the price filter. | |
const finalSpec = new AndSpecification(price_spec, colorOptions) | |
// Filter products ** this.products would be your products array ** | |
const filteredProducts = megaFilter.filter(this.products, finalSpec) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment