UNPKG

@ivujs/i-utils

Version:

前端模块化 JavaScript 工具库

477 lines (473 loc) 13.5 kB
'use strict'; var sort = require('../constants/sort.cjs'); var index = require('../validate/index.cjs'); /** * @module 数组 */ /* 数组计算 */ /** * 数组最小值 * @param {Array} array 数组 * @returns {number} 返回最小值 */ function arrayMin(array) { return Math.min.apply(null, array); } /** * 数组最大值 * @param {array} array 数组 * @returns {number} 返回最大值 */ function arrayMax(array) { return Math.max.apply(null, array); } /** * 数组求和 * @param {Array} array 数组 * @returns {number} 返回和 */ function arraySum(array) { return array.reduce(function (pre, cur) { return pre + cur; }); } /** * 数组求平均值 * @param {Array} array 数组 * @returns {number} 返回平均数 */ function arrayAvg(array) { return arraySum(array) / array.length; } /* 数组比较 */ /** * 数组中是否包含指定的元素 * @param {string|number} value 元素 * @param {Array} array 查找的数组 * @returns {boolean} 返回结果 */ function inArray(value, array) { if (index.isNull(value)) return false; return array.includes(value); } /** * 比较两个数组是否相等 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {boolean} 返回结果 */ function arrayEquals(array1, array2) { if (array1 === array2) return true; if (array1.length !== array2.length) return false; return array1.every((v, i) => v === array2[i]); } /* 数组操作 */ /** * 生成指定长度的数组 * @param {number} length 长度,默认 0 * @returns {Array} 返回数组 */ function arrayCreate(length = 0) { return [...Array(length).keys()]; } /** * 数组指定位置添加元素 * @description 如果数组为空,则在0位置添加元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @param {*} value 添加的元素 * @returns {Array} 返回操作后的数组 */ function arrayInsert(array = [], index = 0, value = undefined) { if (index < 0) return array; if (array.length === 0) { array.push(value); } else { if (index > array.length - 1) { return array; } array.splice(index, 0, value); } return array; } /** * 数组指定位置前面添加元素 * @description 如果数组为空,则在0位置添加元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @param {*} value 添加的元素 * @returns {Array} 返回操作后的数组 */ function arrayInsertBefore(array = [], index = 0, value = undefined) { if (index < 0) return array; if (array.length === 0) { array.push(value); } else { if (index > array.length - 1) { return array; } array.splice(index, 0, value); } return array; } /** * 数组指定位置后面添加元素 * @description 如果数组为空,则在0位置添加元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @param {*} value 添加的元素 * @returns {Array} 返回操作后的数组 */ function arrayInsertAfter(array = [], index = 0, value = undefined) { if (index < 0) return array; if (array.length === 0) { array.push(value); } else { if (index > array.length - 1) { return array; } array.splice(index, 0, array.splice(index, 1, value)[0]); } return array; } /** * 数组指定位置删除元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayRemove(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; array.splice(index, 1); return array; } /** * 数组指定位置前面删除元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayRemoveBefore(array = [], index = 0) { if (index <= 0 || index > array.length - 1) return array; array.splice(index - 1, 1); return array; } /** * 数组指定位置后面删除元素 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayRemoveAfter(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; array.splice(index + 1, 1); return array; } /** * 数组置顶 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayTop(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; array.unshift(array.splice(index, 1)[0]); return array; } /** * 数组置尾 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayBottom(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; array.push(array.splice(index, 1)[0]); return array; } /** * 数组向上移动 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayUp(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; if (index > 0) { array.splice(index - 1, 0, array.splice(index, 1)[0]); } else { array.push(array.splice(index, 1)[0]); } return array; } /** * 数组向下移动 * @param {Array} array 数组 * @param {number} index 下标位置,默认0 * @returns {Array} 返回操作后的数组 */ function arrayDown(array = [], index = 0) { if (index < 0 || index > array.length - 1) return array; if (index < array.length - 1) { array.splice(index + 1, 0, array.splice(index, 1)[0]); } else { array.unshift(array.splice(index, 1)[0]); } return array; } /** * 数组交换元素 * @param {Array} array 数组 * @param {number} sourceIndex 原索引 * @param {number} targetIndex 目标索引 * @returns {Array} 返回操作后的数组 */ function arraySwap(array, sourceIndex, targetIndex) { if (sourceIndex < 0 || targetIndex < 0 || sourceIndex > array.length - 1 || targetIndex > array.length - 1) { return array; } [array[targetIndex], array[sourceIndex]] = [array[sourceIndex], array[targetIndex]]; return array; } /** * 数组排序 * @param {Array} array 数组 * @param {number} mode 排序模式,参考常量集合中 数组常量,默认是升序 * @returns {Array} 返回操作后的数组 */ function arraySort(array, mode = sort.SORT.ASC) { return array.sort((a, b) => { switch (mode) { // 升序 case sort.SORT.ASC: return a - b; // 降序 case sort.SORT.DESC: return b - a; // 随机 case sort.SORT.RANDOM: return Math.random() - 0.5; default: return 0; } }); } /** * 数组属性混合排序 * @description 排序默认为asc升序 * @param {Array} array 数组 * @param {Array} props 排序的属性 * @returns {Array} 返回操作后的数组 */ function arraySortBy(array, props) { return array.sort((a, b) => { for (const item of props) { // 排序配置 let prop = "", order = "asc"; if (index.isObject(item)) { prop = item.prop; order = item.order || "asc"; } else { prop = item; order = "asc"; } // 排序逻辑 if (a[prop] < b[prop]) { return order === "asc" ? -1 : 1; } if (a[prop] > b[prop]) { return order === "asc" ? 1 : -1; } } return 0; }); } /** * 数组元素去重 * @param {Array} array 数组 * @returns {Array} 返回操作后的数组 */ function arrayUnique(array) { if (index.isEmpty(array)) return []; return Array.from(new Set(array)); } /** * 数组打乱元素 * @description 可以适用于一些抽奖人员列表打乱顺序 * @param {Array} array 数组 * @returns {Array} 返回操作后的数组 */ function arrayShuffle(array) { for (let i = 1; i < array.length; i++) { const random = Math.floor(Math.random() * (i + 1)); [array[random], array[i]] = [array[i], array[random]]; } return array; } /* 数组转换 */ /** * 普通数组转树形结构 * @description 包含id和pid属性关系的一维数组,转为children的树形结构 * @param {Array} array 数组 * @param {Object} setting 配置项 * @returns {Array} 返回树形节点 */ function arrayToTree(array, setting = { key: "id", parentKey: "pid", childrenKey: "children", }) { const key = setting.key, parentKey = setting.parentKey, childrenKey = setting.childrenKey; // 数组或者key是否为空 if (!array || array.length === 0 || !key || key === "") return []; // 获得子节点方法 const nodeChildren = function (node, childrenKey, newChildren) { if (!node) { return null; } if (typeof newChildren !== "undefined") { node[childrenKey] = newChildren; } return node[childrenKey]; }; // 声明变量 const result = []; const tempMap = {}; for (let i = 0; i < array.length; i++) { // 如果源数据数组中有children,则需要删除掉,否则会导致和之前的children合并 array[i][childrenKey] && delete array[i][childrenKey]; tempMap[array[i][key]] = array[i]; } for (let i = 0; i < array.length; i++) { const parent = tempMap[array[i][parentKey]]; if (parent && array[i][key] !== array[i][parentKey]) { let children = nodeChildren(parent, childrenKey); if (!children) { children = nodeChildren(parent, childrenKey, []); } children.push(array[i]); } else { result.push(array[i]); } } // 返回结果 return result; } /** * 树形结构转普通数组 * @param {Array} nodes 树形节点 * @param {Object} setting 配置项 * @returns {Array} 返回普通数组 */ function treeToArray(nodes, setting = { childrenKey: "children" }) { const childrenKey = setting.childrenKey; const result = []; for (const node of nodes) { // 删除掉多余空的children if (node[childrenKey] && !node[childrenKey].length) { delete node[childrenKey]; } result.push(node); // 继续执行 if (node[childrenKey] && node[childrenKey].length) { const array = treeToArray(node[childrenKey], setting); array && result.push(...array); } } // 返回结果 return result; } /* 数组求并集,交集,差集等 */ /** * 数组求并集 * @description 数组1 和 数组2 合并一起的元素集合 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {Array} 返回数组 */ function arrayUnion(array1, array2) { return [...new Set(array1.concat(array2))]; } /** * 数组求交集 * @description 数组1 和 数组2 相同的元素集合 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {Array} 返回数组 */ function arrayIntersect(array1, array2) { return [...new Set(array1)].filter((item) => array2.includes(item)); } /** * 数组求差集 * @description 数组1 中不包含 数组2 的元素集合 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {Array} 返回数组 */ function arrayDifference(array1, array2) { return [...new Set(array1)].filter((item) => !array2.includes(item)); } /** * 数组求补集 * @description 数组1 和 数组2 不相同的元素集合 * @param {Array} array1 数组1 * @param {Array} array2 数组2 * @returns {Array} 返回数组 */ function arrayComplement(array1, array2) { return [ ...[...new Set(array1)].filter((item) => !array2.includes(item)), ...[...new Set(array2)].filter((item) => !array1.includes(item)), ]; } exports.arrayAvg = arrayAvg; exports.arrayBottom = arrayBottom; exports.arrayComplement = arrayComplement; exports.arrayCreate = arrayCreate; exports.arrayDifference = arrayDifference; exports.arrayDown = arrayDown; exports.arrayEquals = arrayEquals; exports.arrayInsert = arrayInsert; exports.arrayInsertAfter = arrayInsertAfter; exports.arrayInsertBefore = arrayInsertBefore; exports.arrayIntersect = arrayIntersect; exports.arrayMax = arrayMax; exports.arrayMin = arrayMin; exports.arrayRemove = arrayRemove; exports.arrayRemoveAfter = arrayRemoveAfter; exports.arrayRemoveBefore = arrayRemoveBefore; exports.arrayShuffle = arrayShuffle; exports.arraySort = arraySort; exports.arraySortBy = arraySortBy; exports.arraySum = arraySum; exports.arraySwap = arraySwap; exports.arrayToTree = arrayToTree; exports.arrayTop = arrayTop; exports.arrayUnion = arrayUnion; exports.arrayUnique = arrayUnique; exports.arrayUp = arrayUp; exports.inArray = inArray; exports.treeToArray = treeToArray;