UNPKG

rn-collie

Version:

A UI library for react native.

283 lines (258 loc) 7.12 kB
//提供各种语法糖的工具类 /** * 以流水线的形式执行方法 * const add5 = x => x + 5; * const multiply = (x, y) => x * y; * const multiplyAndAdd5 = pipeFunctions(multiply, add5); * multiplyAndAdd5(5, 2); // 15 * @param fns * @returns {*|(function(...[*]): *)} */ const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))); /** * 方法转换成Promise * @param func * @returns {function(...[*]): Promise<R>} */ const promisify = func => (...args) => new Promise((resolve, reject) => func(...args, (err, result) => (err ? reject(err) : resolve(result))) ); /** * 停留一段事件执行某种操作 * delay(2000).then(() => console.log('Hi!')); // // Promise resolves after 2s * @type {function(...[*]): Promise<R>} */ const delay = promisify((d, cb) => setTimeout(cb, d)); /** * 让方法支持数组 * const arrayMax = spreadOver(Math.max); * arrayMax([1, 2, 3]); // 3 * @param fn * @returns {function(*): *} */ const spreadOver = fn => argsArr => fn(...argsArr); /** * 数组求最大值 * arrayMax([1, 2, 3]); // 3 * @type {function(*): *} */ const arrayMax = spreadOver(Math.max); /** * 数组求最小值 * @type {function(*): *} */ const arrayMin = spreadOver(Math.min); /** * 数组集中判断是否ok * arrayOK([4, 2, 3], x => x > 1); // true * @param arr * @param fn * @returns {boolean} */ const arrayOK = (arr, fn = Boolean) => arr.every(fn); /** * 数组是否包含 * arrayAny([0, 1, 2, 0], x => x >= 2); // true * @param arr * @param fn * @returns {boolean} */ const arrayAny = (arr, fn = Boolean) => arr.some(fn); /** * 数组中出现某个值的次数 * arrayCountOccurrences([1, 1, 2, 1, 2, 3], 1); // 3 * @param arr * @param val * @returns {*} */ const arrayCountOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0); /** * 深层次的展开数组 * arrayDeepFlat([1, [2], [[3], 4], 5]); // [1,2,3,4,5] * @param arr * @returns {*[]} */ const arrayDeepFlat = arr => [].concat(...arr.map(v => (Array.isArray(v) ? arrayDeepFlat(v) : v))); /** * 返回在左数组中右数组没有的数据 * arrayDifference([1, 2, 3], [1, 2, 4]); // [3] * @param a * @param b * @returns {*} */ const arrayDifference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; /** * 自定义返回在左数组中右数组没有的数据 * @param a * @param b * @param fn * @returns {*} */ const arrayDifferenceBy = (a, b, fn) => { const s = new Set(b.map(fn)); return a.filter(x => !s.has(fn(x))); }; /** * 返回两个数组的交集 * arrayHasOther([1, 2, 3], [1, 2, 4]); // [3] * @param a * @param b * @returns {*} */ const arrayHasOther = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); }; /** * 自定义返回两个数组的交集 * arrayHasOther([1, 2, 3], [1, 2, 4]); // [3] * @param a * @param b * @param fn * @returns {*} */ const arrayHasOtherBy = (a, b, fn) => { const s = new Set(b.map(fn)); return a.filter(x => s.has(fn(x))); }; /** * 数组去重 * arrayFilterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1, 3, 5] * @param arr * @returns {*} */ const arrayFilterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); /** * 数组自定义去重 * arrayFilterNonUniqueBy( [ { id: 0, value: 'a' }, { id: 1, value: 'b' }, { id: 2, value: 'c' }, { id: 1, value: 'd' }, { id: 0, value: 'e' } ], (a, b) => a.id == b.id ); // [ { id: 2, value: 'c' } ] * @param arr * @param fn * @returns {*} */ const arrayFilterNonUniqueBy = (arr, fn) => arr.filter((v, i) => arr.every((x, j) => (i === j) === fn(v, x, i, j))); /** * 找到符合条件的最后一个元素 * arrayFindLast([1, 2, 3, 4], n => n % 2 === 1); // 3 * @param arr * @param fn * @returns {*|{routes, index}|{type}} */ const arrayFindLast = (arr, fn) => arr.filter(fn).pop(); /** * 找到符合条件的最后一个元素的位置 * arrayFindLastIndex([1, 2, 3, 4], n => n % 2 === 1); // 2 (index of the value 3) * arrayFindLastIndex([1, 2, 3, 4], n => n === 5); // -1 (default value when not found) * @param arr * @param fn * @returns {*|number} */ const arrayFindLastIndex = (arr, fn) => (arr .map((val, i) => [i, val]) .filter(([i, val]) => fn(val, i, arr)) .pop() || [-1])[0]; /** * 如果提供的谓词函数对集合中的所有元素返回false,则返回true,否则返回false。 * none([0, 1, 3, 0], x => x == 2); // true * none([0, 0, 0]); // true * @param arr * @param fn * @returns {boolean} */ const arrayNone = (arr, fn = Boolean) => !arr.some(fn); /** * 初始化一个数组,该数组包含指定范围内的数字,其中开始和结束(包括它们)和它们的共同区别 * initializeArrayWithRange(5); // [0,1,2,3,4,5] * initializeArrayWithRange(7, 3); // [3,4,5,6,7] * initializeArrayWithRange(9, 0, 2); // [0,2,4,6,8] * @param end * @param start * @param step * @returns {number[]} */ const initializeArrayWithRange = (end, start = 0, step = 1) => Array.from({length: Math.ceil((end - start + 1) / step)}, (v, i) => i * step + start); /** * 用指定的值初始化并填充数组 * initializeArrayWithValues(5, 2); // [2, 2, 2, 2, 2] * @param n * @param val * @returns {any[]} */ const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val); /** * 将数组的所有元素连接到字符串中并返回此字符串。使用分隔符和结尾分隔符 * * join(['pen', 'pineapple', 'apple', 'pen'], ',', '&'); // "pen,pineapple,apple&pen" * join(['pen', 'pineapple', 'apple', 'pen'], ','); // "pen,pineapple,apple,pen" * join(['pen', 'pineapple', 'apple', 'pen']); // "pen,pineapple,apple,pen" * @param arr * @param separator * @param end * @returns {*} */ const join = (arr, separator = ',', end = separator) => arr.reduce( (acc, val, i) => i === arr.length - 2 ? acc + val + end : i === arr.length - 1 ? acc + val : acc + val + separator, '' ); /** * 生成所有元素的排列组合 * arrayPermutations([1, 33, 5]); // [ [ 1, 33, 5 ], [ 1, 5, 33 ], [ 33, 1, 5 ], [ 33, 5, 1 ], [ 5, 1, 33 ], [ 5, 33, 1 ] ] * @param arr * @returns {*[]|*} */ const arrayPermutations = arr => { if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr; return arr.reduce( (acc, item, i) => acc.concat( arrayPermutations([...arr.slice(0, i), ...arr.slice(i + 1)]).map(val => [item, ...val]) ), [] ); }; export default { pipeFunctions, promisify, delay, spreadOver, arrayMax, arrayMin, arrayOK, arrayAny, arrayCountOccurrences, arrayDeepFlat, arrayDifference, arrayDifferenceBy, arrayHasOther, arrayHasOtherBy, arrayFilterNonUnique, arrayFilterNonUniqueBy, arrayFindLast, arrayFindLastIndex, arrayNone, arrayPermutations, initializeArrayWithRange, initializeArrayWithValues, join }