Skip to content

Instantly share code, notes, and snippets.

@dinocarl
Last active February 7, 2024 21:58
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 dinocarl/7d99c8a6b075ea16e4acd477b2138df4 to your computer and use it in GitHub Desktop.
Save dinocarl/7d99c8a6b075ea16e4acd477b2138df4 to your computer and use it in GitHub Desktop.
const filterOperations = {
eq: equals,
neq: complement(equals),
lt: gt,
gt: lt,
lte: gte,
gte: lte,
includes: includes,
}
const filterCombiners = {
and: allPass,
or: anyPass,
}
const filterer = ([propName, operator, val]) => pathSatisfies(
filterOperations[operator](val),
propName.split('.')
)
const tacitOr = (filterTuple) => !Array.isArray(path([0, 1], filterTuple))
? anyPass
: head
const parseFilterTuples = (filterTuple, idx) => Array.isArray(nth(1, filterTuple))
? propOr(anyPass, head(filterTuple), filterCombiners)(map(parseFilterTuples, (tail(filterTuple))))
: has(nth(1, filterTuple), filterOperations)
? filterer(filterTuple)
: always(identity);
// 1. Use the tacitOr to determine whether to create
// a union out of a list of operations
// 2. Interpret the filtering commands by iterating
// over the tuples to create filtering functions
// 3. Apply the filtering function created by 2) to
// the function returned by 1) which returns a
// consolidated filtering function
const parseableFilter = (recipe) => tacitOr(recipe)(
map(
parseFilterTuples,
recipe
)
)
const data = [
{val: -3, type: 'other'},
{val: -2, type: 'other'},
{val: -1, type: 'other'},
{val: 1, type: 'other'},
{val: 2, type: 'prime'},
{val: 3, type: 'prime'},
{val: 4, type: 'composite'},
{val: 5, type: 'prime'},
{val: 6, type: 'composite'},
{val: 7, type: 'prime'},
{val: 8, type: 'composite'},
{val: 9, type: 'composite'},
]
const posts = [
{
id: 1,
title: "Et Ultrices Posuere",
author: { firstName: "Ashby", lastName: "Parfrey" },
tags: [ "Travel", "Press Release" ]
},
{
id: 2,
title: "Nulla Nisl",
author: { firstName: "Jacki", lastName: "Mitchley" },
tags: [ "Rant", "Finance" ]
},
{
id: 3,
title: "Natoque Penatibus Et Magnis Dis Parturient",
author: { firstName: "Rene", lastName: "McCaughey" },
tags: [ "Press Release", "Health", "Rant", "Travel" ]
},
{
id: 4,
title: "At Velit Vivamus Vel Nulla Eget",
author: { firstName: "Rafa", lastName: "Stockey" },
tags: [ "Press Release", "Finance", "Health", "Entertainment" ]
},
{
id: 5,
title: "Amet Eros",
author: { firstName: "Arabella", lastName: "Climance" },
tags: [ "Press Release", "Travel", "Rant", "Arts and Leisure" ]
},
{
id: 6,
title: "Tortor Quis Turpis Sed",
author: { firstName: "Jaquenetta", lastName: "Drinkale" },
tags: [ "Press Release", "Health", "Arts and Leisure" ]
},
{
id: 7,
title: "Aenean Fermentum Donec Ut Mauris Eget Massa",
author: { firstName: "Marv", lastName: "Schroder" },
tags: [ "Finance", "Travel" ]
},
{
id: 8,
title: "Convallis Nunc Proin At Turpis A",
author: { firstName: "Christy", lastName: "Yates" },
tags: [ "Press Release", "Rant", "Arts and Leisure" ]
},
{
id: 9,
title: "Primis In Faucibus Orci Luctus",
author: { firstName: "Dag", lastName: "Damant" },
tags: [ "Travel", "Press Release", "Arts and Leisure", "Finance" ]
},
{
id: 10,
title: "Amet Lobortis Sapien Sapien",
author: { firstName: "Hallie", lastName: "Feely" },
tags: [ "Arts and Leisure", "Travel", "Health" ]
}
]
const filterRecipe = [
['or',
['val', 'lt', 0]],
['and',
['val', 'gt', 4],
['type', 'eq', 'prime']]]
const filterRecipe2 = [
['val', 'lt', 0],
['val', 'gt', 4]]
const filterRecipe3 = [
['or',
['val', 'lt', 0],
['and',
['val', 'gt', 4],
['type', 'eq', 'prime']]]]
const filterRecipe4 = [
['and',
['author.lastName', 'lt', 'M'],
['or',
['tags', 'includes', 'Rant'],
['tags', 'includes', 'Travel']]]]
filter(
parseableFilter(filterRecipe4),
posts
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment