/** * Wrapper for Object functions */ class ObjectHelper { static values(obj) { return Object.values(obj) } static entries(obj) { return Object.entries(obj) } static reduce(obj, fn, init) { return this.entries(obj).reduce(fn, init || {}) } static reduceTo(arr, key_fn, val_fn, init) { return arr.reduce((acc, el, id) => ({ ...acc, [key_fn(el, id)]: val_fn(el, id) }), init || {}) } static map(obj, fn) { return this.entries(obj).map(fn) } static flatMap(obj, fn, unique = false) { const map = this.entries(obj).flatMap(fn) if (unique) { return map.filter(UniqueList.filter) } return map } static filter(obj, predicate) { let filtered = {} for (const key in obj) { if (obj.hasOwnProperty(key) && predicate(key, obj[key])) { filtered[key] = obj[key] } } return filtered } /** * Map parent: { child } to 'parent.child' for fields */ static flattenTree(source, fields, split = '.') { return fields.reduce((flat, field) => { let parts = field.split(split) let target = source while (parts.length > 1) { // Walk tree target = target[parts.shift()] || {} } flat[field] = target[parts.shift()] return flat }, {}) } /** * Map 'parent.child' to parent: { child } */ static expandTree(source, split = '.') { return this.reduce(source, (tree, [key, value]) => { let parts = key.split(split) let target = tree while (parts.length > 1) { // Create tree let child = parts.shift() if (target[child] == undefined) { target[child] = {} } target = target[child] } target[parts.shift()] = value return tree }) } }