Skip to content

Instantly share code, notes, and snippets.

@bultas
Last active February 20, 2017 17:40
Show Gist options
  • Save bultas/b71dd82db859fecb16579d30134bb6b0 to your computer and use it in GitHub Desktop.
Save bultas/b71dd82db859fecb16579d30134bb6b0 to your computer and use it in GitHub Desktop.
Filter and Aggregation - immutable, functional, reduce example
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