UNPKG

ice.fo.utils

Version:

103 lines (87 loc) 2.59 kB
import _groupBy from 'lodash/groupBy' import _get from 'lodash/get' import _isEqual from 'lodash/isEqual' import _isFunction from 'lodash/isFunction' /** * Group a list of objects by [key] name. The [key] also supports properties path access e.g. 'user.profile.name' * * @example * groupByKey([{name: 'nikochin', age: 10}, {name: 'nikochin', age: 30}, {name: 'edward', age: 10}], 'name', true); // returns [ [{name: 'nikochin', age: 10}, {name: 'nikochin', age: 30}], [{name: 'edward', age: 10}] ] * * @param {any[]} list * @param {string|string[]} key * @param {boolean} keepOrder * @returns An list of objects list grouped by key */ export function groupByKey (list, key, keepOrder = false) { if (!keepOrder) { return Object.values(_groupBy(list, i => _get(i, key))) } const result = [] const firstItem = _get(list, '0') const isFuncKey = _isFunction(key) let previousValue = isFuncKey ? key(firstItem) : _get(firstItem, key) let previousList = [] list.forEach((item) => { const value = isFuncKey ? key(item) : _get(item, key) if (_isEqual(value, previousValue)) { previousList.push(item) } else { result.push(previousList) previousList = [item] previousValue = value } }) if (previousList.length) { result.push(previousList) } return result } /** * Merge 2 array and remove previous duplicate * * @param {any[]} a * @param {any[]} b * @param {(any) => string} indicator * @returns */ export function mergeUnique (a, b, indicator = i => i.id) { const result = [] const dict = {} a.forEach((i, index) => { result.push(i) dict[indicator(i)] = index }) b.forEach((i) => { const foundIndex = dict[indicator(i)] if (foundIndex != null) { result.splice(foundIndex, 1, i) } else { result.push(i) } }) return result } /** * Creates an array of elements split into groups with length size. If array can't be split evenly, the final chunk will be the remaining elements. * * @example * splitIntoChunks([1,2,3,4], 2); // returns [ [1,2], [3,4] ] * splitIntoChunks([1,2,3,4], 3); // returns [ [1,2,3], [4] ] * splitIntoChunks([1,2,3,4], 5); // returns [ [1,2,3,4] ] * * @param array * @param length * @returns {[]} */ export function splitIntoChunks (array, length) { if (array.length < length) { return [array] } const result = [] const chunkCount = Math.ceil(array.length / length) for (let i = 0; i < chunkCount; i++) { result.push(array.slice(i * length, i * length + length)) } return result }