diff options
Diffstat (limited to 'addons/web/static/src/js/core')
| -rw-r--r-- | addons/web/static/src/js/core/utils.js | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/addons/web/static/src/js/core/utils.js b/addons/web/static/src/js/core/utils.js index 560f3a94466..17ce0e080b2 100644 --- a/addons/web/static/src/js/core/utils.js +++ b/addons/web/static/src/js/core/utils.js @@ -205,6 +205,28 @@ var diacriticsMap = { const patchMap = new WeakMap(); +/** + * Helper function returning an extraction handler to use on array elements to + * return a certain attribute or mutated form of the element. + * + * @private + * @param {string | function} criterion + * @returns {(element: any) => any} + */ +function _getExtractorFrom(criterion) { + if (criterion) { + switch (typeof criterion) { + case 'string': return element => element[criterion]; + case 'function': return criterion; + default: throw new Error( + `Expected criterion of type 'string' or 'function' and got '${typeof criterion}'` + ); + } + } else { + return element => element; + } +} + var utils = { /** @@ -304,6 +326,31 @@ var utils = { }); }, /** + * Returns an object holding different groups defined by a given criterion + * or a default one. Each group is a subset of the original given list. + * The given criterion can either be: + * - a string: a property name on the list elements which value will be the + * group name, + * - a function: a handler that will return the group name from a given + * element. + * + * @param {any[]} list + * @param {string | function} [criterion] + * @returns {Object} + */ + groupBy: function (list, criterion) { + const extract = _getExtractorFrom(criterion); + const groups = {}; + for (const element of list) { + const group = String(extract(element)); + if (!(group in groups)) { + groups[group] = []; + } + groups[group].push(element); + } + return groups; + }, + /** * Returns a human readable number (e.g. 34000 -> 34k). * * @param {number} number @@ -656,22 +703,13 @@ var utils = { * - a function: a handler that will return the sortable primitive from a given element. * * @param {any[]} array - * @param {(string|function)} [criterion] + * @param {string | function} [criterion] */ sortBy: function (array, criterion) { - let getter; - if (criterion) { - switch (typeof criterion) { - case 'string': getter = element => element[criterion]; break; - case 'function': getter = criterion; break; - default: throw new Error(`Expected criterion of type 'string' or 'function' and got '${typeof criterion}'`); - } - } else { - getter = element => element; - } + const extract = _getExtractorFrom(criterion); return array.slice().sort((elA, elB) => { - const a = getter(elA); - const b = getter(elB); + const a = extract(elA); + const b = extract(elB); if (isNaN(a) && isNaN(b)) { return a > b ? 1 : a < b ? -1 : 0; } else { |
