Skip to content

Instantly share code, notes, and snippets.

@nickgrato
Created January 20, 2022 17:29
Show Gist options
  • Save nickgrato/dc55cbf6c8fa99d5ea49965bacd26405 to your computer and use it in GitHub Desktop.
Save nickgrato/dc55cbf6c8fa99d5ea49965bacd26405 to your computer and use it in GitHub Desktop.
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