Last active
February 20, 2017 17:40
-
-
Save bultas/b71dd82db859fecb16579d30134bb6b0 to your computer and use it in GitHub Desktop.
Filter and Aggregation - immutable, functional, reduce example
This file contains hidden or 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
import { Map } from 'immutable'; | |
const items = Map({ | |
id1: Map({ | |
name: 'Item Name', | |
isActive: true | |
}), | |
id2: Map({ | |
name: 'Another Name', | |
isActive: false | |
}) | |
}); | |
const FILTER1 = 'filter1'; | |
const FILTER2 = 'filter2'; | |
const filters = Map({ | |
[FILTER1]: Map({ | |
getValue: (item) => item.get('name'), | |
filter: (value, filterValue) => stringContains(filterValue, value) | |
}), | |
[FILTER2]: Map({ | |
getValue: (item) => item.get('isActive'), | |
filter: (value, filterValue) => value === filterValue | |
}) | |
}); | |
const activeFilters = Map({ | |
FILTER1: 'name', | |
FILTER2: 'true' | |
}); | |
function stringifyValue(value) { | |
return `${value}`; | |
} | |
function createIsItemAllowedReduce(item, filters) { | |
return (allowed, filterValue, filterID) => { | |
if (allowed) { | |
const actualFilter = filters.get(filterID); | |
const filterFN = actualFilter.get('filter'); | |
const filteredValue = actualFilter.get('getValue')(item); | |
return filterFN( | |
stringifyValue(filteredValue), | |
filterValue | |
); | |
} | |
return allowed; | |
}; | |
} | |
function createItemsFilterReduce(filters, activeFilters, createIsAllowedReduce) { | |
return (filteredItems, item) => { | |
const isItemAllowed = activeFilters.reduce( | |
createIsAllowedReduce(item, filters), | |
true | |
); | |
if (isItemAllowed) { | |
return filteredItems.set(item.get('id'), item); | |
} | |
return filteredItems; | |
}; | |
} | |
function createItemReduce(filters, createExtraReduce) { | |
return (data, item) => { | |
return filters.reduce( | |
createExtraReduce(item), | |
data | |
); | |
}; | |
} | |
function createAggregationReduce(item) { | |
return (data, filterFunctions, filterID) => { | |
return data.updateIn( | |
[ | |
filterID, | |
stringifyValue( | |
filterFunctions.get('getValue')(item) | |
) | |
], | |
0, | |
(count) => count + 1 | |
); | |
}; | |
} | |
export function filterAndAggregateItemsHelper(filters, activeFilters, items) { | |
const aggregationReduce = createItemReduce(filters, createAggregationReduce); | |
const allItemsAggregations = items.reduce( | |
aggregationReduce, | |
Map() | |
); | |
const filteredItems = items.reduce( | |
createItemsFilterReduce(filters, activeFilters, createIsItemAllowedReduce), | |
Map() | |
); | |
const filteredItemsAggregations = filteredItems.reduce( | |
aggregationReduce, | |
Map() | |
); | |
return Map({ | |
filteredItems, | |
aggregations: Map({ | |
allItemsAggregations, | |
filteredItemsAggregations | |
}) | |
}); | |
} | |
const itemResults = filterAndAggregateItems(filters, activeFilters, items); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment