-
-
Save gambitier/f94e00c388f9bdb72d28b79dcec92e5b to your computer and use it in GitHub Desktop.
Revisions
-
leofavre revised this gist
Jun 15, 2017 . 1 changed file with 9 additions and 8 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -7,16 +7,17 @@ * strings for iteratees. */ const deepGroupBy = (collection, ...iteratees) => { let paths = collection.map(value => iteratees.map(iteratee => iteratee(value))), result = {}; paths.forEach((path, index) => { let currentValue = _simpleAt(result, path) || [], newValue = currentValue.concat([collection[index]]); _simpleSet(result, path, newValue); }); return result; }; const _isPlainObject = arg => -
leofavre revised this gist
Jun 15, 2017 . No changes.There are no files selected for viewing
-
leofavre revised this gist
Jun 15, 2017 . 1 changed file with 31 additions and 93 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,106 +1,44 @@ /** * Part of [Canivete](http://canivete.leofavre.com/#deepgroupby) * * Groups the contents of an array by one or more iteratees. * Unlike Lodash [`groupBy()`](https://lodash.com/docs/4.17.4#groupBy), * this function can create nested groups, but cannot receive * strings for iteratees. */ const deepGroupBy = (collection, ...iteratees) => { let paths = collection.map(value => iteratees.map(iteratee => iteratee(value))), result = {}; paths.forEach((path, index) => { let currentValue = _simpleAt(result, path); let newValue = (typeof currentValue === "undefined") ? [collection[index]] : currentValue.concat([collection[index]]); _simpleSet(result, path, newValue); }); return result; }; const _isPlainObject = arg => arg != null && typeof arg == "object" && arg.constructor == Object; const _parsePath = path => Array.isArray(path) ? path : `${path}`.split("."); const _simpleAt = (obj, path) => _parsePath(path).reduce((obj, key) => { return (obj != null && obj.hasOwnProperty(key)) ? obj[key] : undefined; }, obj); const _simpleSet = (obj, path, value) => _parsePath(path).reduce((obj, key, index, arr) => { let isLast = (index === arr.length - 1); if (!obj.hasOwnProperty(key) || (!isLast && !_isPlainObject(obj[key]))) { obj[key] = {}; } return (!isLast) ? obj[key] : obj[key] = value; }, obj); export default deepGroupBy; -
leofavre renamed this gist
Jun 14, 2017 . 1 changed file with 5 additions and 7 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -8,8 +8,6 @@ import at from "lodash-es/at"; * A recursive implementation of LoDash [`groupBy()`](https://lodash.com/docs/4.17.4#groupBy) * that can take one or more iteratees to create nested groups. * * @category Collection * * @param {Array.<Object>} collection The array of objects. @@ -21,7 +19,7 @@ import at from "lodash-es/at"; * const getLength = str => str.length; * const getFirstLetter = str => str.slice(0, 1); * * deepGroupBy(["one", "two", "three"], getLength, getFirstLetter); * // => { * // => "3": {"o": ["one"], "t": ["two"]}, * // => "5": {"t": ["three"]} @@ -32,7 +30,7 @@ import at from "lodash-es/at"; * const getLength = str => str.length; * const getFirstLetter = str => str.slice(0, 1); * * deepGroupBy(["one", "two", "three"], getFirstLetter, getLength); * // => { * // => "o": {"3": ["one"]}, * // => "t": {"3": ["two"], "5": ["three"]} @@ -73,14 +71,14 @@ import at from "lodash-es/at"; * const getStateName = item => item.state; * const getCityName = item => item.city; * * deepGroupBy(stores, getStateName, getCityName); * // => { * // => "SP": { "Campinas": [...], "São Paulo": [...] }, * // => "RJ": { "Búzios": [...], "Rio de Janeiro": [...] }, * // => "DF": { "Brasília": [...] } * // => } */ const deepGroupBy = (collection, ...iteratees) => { const groupBranch = (collection, iteratee, keys = []) => (keys.length === 0) ? groupBy(collection, iteratee) : set(collection, formatPath(keys), groupBy(simpleAt(collection, keys), iteratee)); const getKeysAt = (collection, keys = []) => (keys.length === 0) ? Object.keys(collection) : Object.keys(simpleAt(collection, keys)); @@ -105,4 +103,4 @@ const recursiveGroupBy = (collection, ...iteratees) => { return doGroupByRecursive(collection, iteratees); }; export default deepGroupBy; -
leofavre revised this gist
May 21, 2017 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ import set from "lodash-es/set"; import at from "lodash-es/at"; /** * Part of [Canivete](http://canivete.leofavre.com/) * * A recursive implementation of LoDash [`groupBy()`](https://lodash.com/docs/4.17.4#groupBy) * that can take one or more iteratees to create nested groups. -
leofavre revised this gist
May 17, 2017 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ import set from "lodash-es/set"; import at from "lodash-es/at"; /** * Part of [Canivete](https://leofavre.github.io/canivete/) * * A recursive implementation of LoDash [`groupBy()`](https://lodash.com/docs/4.17.4#groupBy) * that can take one or more iteratees to create nested groups. @@ -39,6 +39,7 @@ import at from "lodash-es/at"; * // => } * * @example * * const stores = [{ * "name": "Iguatemi", * "city": "Campinas", -
leofavre revised this gist
May 17, 2017 . 2 changed files with 107 additions and 80 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,80 +0,0 @@ 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,107 @@ import groupBy from "lodash-es/groupBy"; import set from "lodash-es/set"; import at from "lodash-es/at"; /** * Part of [Canivete](http://leofavre.github.io/canivete/) * * A recursive implementation of LoDash [`groupBy()`](https://lodash.com/docs/4.17.4#groupBy) * that can take one or more iteratees to create nested groups. * * @todo Refactor and separate functions in their own files. * * @category Collection * * @param {Array.<Object>} collection The array of objects. * @param {...Function} [...iteratees] The functions used to group the array of objects by their results. * @return {Object} The resulting object. * * @example * * const getLength = str => str.length; * const getFirstLetter = str => str.slice(0, 1); * * recursiveGroupBy(["one", "two", "three"], getLength, getFirstLetter); * // => { * // => "3": {"o": ["one"], "t": ["two"]}, * // => "5": {"t": ["three"]} * // => } * * @example * * const getLength = str => str.length; * const getFirstLetter = str => str.slice(0, 1); * * recursiveGroupBy(["one", "two", "three"], getFirstLetter, getLength); * // => { * // => "o": {"3": ["one"]}, * // => "t": {"3": ["two"], "5": ["three"]} * // => } * * @example * const stores = [{ * "name": "Iguatemi", * "city": "Campinas", * "state": "SP" * }, { * "name": "Jardins", * "city": "São Paulo", * "state": "SP" * }, { * "name": "Iguatemi", * "city": "São Paulo", * "state": "SP" * }, { * "name": "Pedras", * "city": "Búzios", * "state": "RJ" * }, { * "name": "Ipanema", * "city": "Rio de Janeiro", * "state": "RJ" * }, { * "name": "Leblon", * "city": "Rio de Janeiro", * "state": "RJ" * }, { * "name": "ParkShopping", * "city": "Brasília", * "state": "DF" * }]; * * const getStateName = item => item.state; * const getCityName = item => item.city; * * recursiveGroupBy(stores, getStateName, getCityName); * // => { * // => "SP": { "Campinas": [...], "São Paulo": [...] }, * // => "RJ": { "Búzios": [...], "Rio de Janeiro": [...] }, * // => "DF": { "Brasília": [...] } * // => } */ const recursiveGroupBy = (collection, ...iteratees) => { const groupBranch = (collection, iteratee, keys = []) => (keys.length === 0) ? groupBy(collection, iteratee) : set(collection, formatPath(keys), groupBy(simpleAt(collection, keys), iteratee)); const getKeysAt = (collection, keys = []) => (keys.length === 0) ? Object.keys(collection) : Object.keys(simpleAt(collection, keys)); const simpleAt = (collection, keys) => at(collection, formatPath(keys))[0]; const formatPath = (keys = []) => keys.join(".") || undefined; const doGroupByRecursive = (collection, iteratees = [], keys = []) => { if (iteratees.length > 0) { let result = groupBranch(collection, iteratees[0], keys); getKeysAt(result, keys).forEach(key => { doGroupByRecursive(result, iteratees.slice(1), keys.concat([key])); }); return result; } return collection; }; return doGroupByRecursive(collection, iteratees); }; export default recursiveGroupBy; -
leofavre revised this gist
May 4, 2017 . No changes.There are no files selected for viewing
-
leofavre revised this gist
May 4, 2017 . 1 changed file with 58 additions and 4 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -2,25 +2,79 @@ import groupBy from "lodash-es/groupBy"; import set from "lodash-es/set"; import at from "lodash-es/at"; /** * A recursive implementation of LoDash [`groupBy()`](https://lodash.com/docs/4.17.4#groupBy) * that can take one or many iteratees to create nested groups. * * @category Collection * * @param {Array.<Object>} collection The array of objects. * @param {...Function} [...iteratees] The functions used to group the array of objects by their results. * @return {Object} The resulting object. * * @example * const stores = [{ * name: "Iguatemi", * city: "Campinas", * state: "SP" * }, { * name: "Jardins", * city: "São Paulo", * state: "SP" * }, { * name: "Iguatemi", * city: "São Paulo", * state: "SP" * }, { * name: "Pedras", * city: "Búzios", * state: "RJ" * }, { * name: "Ipanema", * city: "Rio de Janeiro", * state: "RJ" * }, { * name: "Leblon", * city: "Rio de Janeiro", * state: "RJ" * }, { * name: "ParkShopping", * city: "Brasília", * state: "DF" * }]; * * const getStateName = item => item.state; * const getCityName = item => item.city; * * groupByRecursive(stores, getStateName, getCityName); * // => { * // => "SP": { "Campinas": [...], "São Paulo": [...] }, * // => "RJ": { "Búzios": [...], "Rio de Janeiro": [...] }, * // => "DF": { "Brasília": [...] } * // => } */ const groupByRecursive = (collection, ...iteratees) => { const doGroup = (collection, iteratee, keys = []) => (keys.length === 0) ? groupBy(collection, iteratee) : set(collection, formatPath(keys), groupBy(simpleAt(collection, keys), iteratee)); const getKeysAt = (collection, keys = []) => (keys.length === 0) ? Object.keys(collection) : Object.keys(simpleAt(collection, keys)); const simpleAt = (collection, keys) => at(collection, formatPath(keys))[0]; const formatPath = (keys = []) => (keys.length === 0) ? undefined : keys.join("."); const doGroupByRecursive = (collection, iteratees = [], keys = []) => { if (iteratees.length > 0) { let result = doGroup(collection, iteratees[0], keys); getKeysAt(result, keys).forEach(key => { doGroupByRecursive(result, iteratees.slice(1), keys.concat([key])); }); return result; } return collection; }; return doGroupByRecursive(collection, iteratees); }; export default groupByRecursive; -
leofavre revised this gist
Apr 4, 2017 . No changes.There are no files selected for viewing
-
leofavre revised this gist
Apr 4, 2017 . No changes.There are no files selected for viewing
-
leofavre created this gist
Apr 4, 2017 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,26 @@ import groupBy from "lodash-es/groupBy"; import set from "lodash-es/set"; import at from "lodash-es/at"; function groupByRecursive(collection, ...iteratees) { const doGroup = (collection, iteratee, keys = []) => (keys.length === 0) ? groupBy(collection, iteratee) : set(collection, formatPath(keys), groupBy(simpleAt(collection, keys), iteratee)); const getKeysAt = (collection, keys = []) => (keys.length === 0) ? Object.keys(collection) : Object.keys(simpleAt(collection, keys)); const simpleAt = (collection, keys) => at(collection, formatPath(keys))[0]; const formatPath = (keys = []) => (keys.length === 0) ? undefined : keys.join("."); function doGroupByRecursive(collection, iteratees = [], keys = []) { if (iteratees.length > 0) { let result = doGroup(collection, iteratees[0], keys); getKeysAt(result, keys).forEach(key => { doGroupByRecursive(result, iteratees.slice(1), keys.concat([key])); }); return result; } return collection; } return doGroupByRecursive(collection, iteratees); } export default groupByRecursive;