npm install zpy-tools
const zpyTools = require('zpy-tools');
/**
* 格式化时间功能
*
* @param {Date} date 时间对象
* @param {String} format 格式化字符串,默认为 "YYYY-MM-DD HH:mm:ss"
*/
console.log(zpyTools.dateFormat(new Date(), 'yyyy-MM-dd')); // "2024-05-20"
console.log(zpyTools.dateFormat(new Date(), 'hh:mm:ss')); // "13:14:52"
console.log(zpyTools.dateFormat(new Date())); // "2024-05-20 13:14:52"
/**
* 获取两个日期之间的时间差
*
* @param {Date} date1 日期对象1
* @param {Date} date2 日期对象2
* @param {String} unit 时间单位,可选值:'year', 'month', 'day', 'hour', 'minute', 'second'(默认)
* @param {Number} decimal 保留小数位数,默认为 2
*/
const date1 = new Date('2024-01-01');
const date2 = new Date('2024-01-10');
console.log(zpyTools.dateDiff(date1, date2)); // 777600
console.log(zpyTools.dateDiff(date1, date2, 'minute')); // 12960
console.log(zpyTools.dateDiff(date1, date2, 'hour')); // 216
console.log(zpyTools.dateDiff(date1, date2, 'day')); // 9
console.log(zpyTools.dateDiff(date1, date2, 'week')); // 1.29
console.log(zpyTools.dateDiff(date1, date2, 'week', 0)); // 1
/**
* 日期浮动
*
* @param {Date} date 日期对象
* @param {String} unit 浮动的单位,可选值:'year', 'month', 'day', 'hour', 'minute', 'second'
* @param {Number} value 浮动的值
*/
const date = new Date("2023-04-01");
console.log(zpyTools.dateFloat(date, 'day', 5)); // '2023-04-06'
console.log(zpyTools.dateFloat(date, 'month', 3)); // '2023-07'
console.log(zpyTools.dateFloat(date, 'year', -1)); // '2022'
console.log(zpyTools.dateFloat(date, 'hour', 10)); // '2023-04-01 18'
console.log(zpyTools.dateFloat(date, 'minute', 30)); // '2023-04-01 08:30'
console.log(zpyTools.dateFloat(date, 'second', 60)); // '2023-04-01 08:01:00'
/**
* 文件大小转换功能
*
* @param {Number} size 文件大小
* @param {String} fromUnit 源单位
* @param {String} toUnit 目标单位
* @param {Number} decimal 保留小数位数,默认为 2
*/
conosle.log(zpyTools.fileSizeConvert(2000, 'KB', 'MB')); // 输出 "1.95 MB"
conosle.log(zpyTools.fileSizeConvert(1024, 'KB', 'MB', 2)); // 输出 "1.00 MB"
/**
* 文件大小格式化功能
*
* @param {Number} size 文件大小 - kb
* @param {Number} decimal 保留小数位数,默认为 2
*/
conosle.log(zpyTools.fileSizeFormat(2000)); // 输出 "1.95 MB"
conosle.log(zpyTools.fileSizeFormat(1024, 2)); // 输出 "1.00 MB"
/**
* File 文件转 Baes64
* @param {File} file 文件
* @returns {string} base64 字符串
*/
conosle.log(zpyTools.fileToBase64(file)); // "data:image/*;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
/**
* Baes64 文件转 File
* @param {String} base64 base64字符串
* @returns {File} File 对象
*/
conosle.log(zpyTools.base64ToFile('data:image/*;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')); // new File()
/**
* 向 localStorage 写入数据
* @param {string} key - 存储的键名
* @param {*} value - 要存储的值,可以是字符串、数字、对象等,但对象会被转换为 JSON 字符串存储
*/
zpyTools.setLocalStorage("user", { name: "Alice", age: 30 });
zpyTools.setLocalStorage("score", 100);
zpyTools.setLocalStorage("message", "Hello, world!");
zpyTools.setLocalStorage("", "invalid key"); // 抛出 TypeError
zpyTools.setLocalStorage("invalidValue", function() {}); // 抛出 TypeError
/**
* 从 localStorage 读取数据
* @param {string} key - 要读取的键名
* @returns {*} - 存储的值,如果是对象会被自动解析回原对象;如果键不存在或发生错误则返回 null
*/
console.log(zpyTools.getLocalStorage("user")); // { name: "Alice", age: 30 }
console.log(zpyTools.getLocalStorage("score")); // 100
console.log(zpyTools.getLocalStorage("message")); // "Hello, world!"
console.log(zpyTools.getLocalStorage("nonexistentKey")); // 返回 null
console.log(zpyTools.getLocalStorage("")); // 抛出 TypeError
/**
* 检查值是否为空
* @param {*} value - 要检查的值
* @returns {Boolean} - 如果值为空,则返回 true;否则返回 false
*/
console.log(zpyTools.isEmpty(null)); // true
console.log(zpyTools.isEmpty(undefined)); // true
console.log(zpyTools.isEmpty("")); // true
console.log(zpyTools.isEmpty([])); // true
console.log(zpyTools.isEmpty({})); // true
console.log(zpyTools.isEmpty(false)); // false
console.log(zpyTools.isEmpty(0)); // false
console.log(zpyTools.isEmpty("some string")); // false
console.log(zpyTools.isEmpty([1, 2, 3])); // false
console.log(zpyTools.isEmpty({ key: "value" })); // false
/**
* 检查是否为合法的URL
* @param {string} url - 要检查的URL字符串
* @returns {Boolean} - 如果是合法的URL,则返回 true;否则返回 false
*/
console.log(zpyTools.isURL("https://www.example.com")); // true
console.log(zpyTools.isURL("http://example.com/path?query=123")); // true
console.log(zpyTools.isURL("ftp://example.com")); // false, 不支持 ftp 协议
console.log(zpyTools.isURL("")); // false
console.log(zpyTools.isURL(" ")); // false
console.log(zpyTools.isURL(123)); // 抛出 TypeError
/**
* 检查是否为合法的电子邮件地址
* @param {string} email - 要检查的电子邮件字符串
* @returns {Boolean} - 如果是合法的电子邮件,则返回 true;否则返回 false
*/
console.log(zpyTools.isEmail("user@example.com")); // true
console.log(zpyTools.isEmail("User.Name+tag+sorting@example.com")); // true
console.log(zpyTools.isEmail("user@sub.example.co.uk")); // true
console.log(zpyTools.isEmail("invalid-email")); // false
console.log(zpyTools.isEmail("")); // false
console.log(zpyTools.isEmail(" ")); // false
console.log(zpyTools.isEmail(123)); // 抛出 TypeError
/**
* 检查是否为合法的中国手机号码
* @param {string|number} phone - 要检查的手机号码,可以是字符串或数字
* @returns {Boolean} - 如果是合法的手机号码,则返回 true;否则返回 false
*/
console.log(zpyTools.isMobile("13800138000")); // true
console.log(zpyTools.isMobile(13800138000)); // true
console.log(zpyTools.isMobile("12345678901")); // false, 不符合中国手机号码格式
console.log(zpyTools.isMobile("")); // false
console.log(zpyTools.isMobile(" ")); // false
console.log(zpyTools.isMobile("abc123")); // false, 包含非数字字符
console.log(zpyTools.isMobile(null)); // 抛出 TypeError
/**
* 获取数据类型
* @param {*} value - 值
* @returns {String} 数据类型
*/
console.log(zpyTools.getDataType(123)); // "number"
console.log(zpyTools.getDataType("hello")); // "string"
console.log(zpyTools.getDataType(true)); // "boolean"
console.log(zpyTools.getDataType([])); // "array"
console.log(zpyTools.getDataType(new Date())); // "date"
console.log(zpyTools.getDataType(/abc/)); // "regexp"
console.log(zpyTools.getDataType(null)); // "null"
console.log(zpyTools.getDataType(undefined)); // "undefined"
console.log(zpyTools.getDataType({})); // "object"
console.log(zpyTools.getDataType(function() {})); // "function"
/**
* 对象深拷贝
* @param {*} data - 值
* @returns {*} 拷贝后的值
*/
console.log(zpyTools.deepClone({name: "对象深拷贝"})); // {name: "对象深拷贝"}
/**
* 数组排序
* 对一维数组或二维数组(对象数组)进行排序。
* 根据指定的键对对象数组进行排序,并且可以处理混合了数字和字符串的值,确保数字部分被正确解析和比较。
* 此外,该函数支持正序和倒序排序,并允许用户通过提供 locales 和 compareOptions 来定制字符串比较的行为。
* @param {Array} arr - 要排序的数组
* @param {Object} options - 排序选项
* key - 排序的键名,默认为空
* isDesc - 是否降序,默认为true
* locales - 比较时使用的本地化信息,默认为空
* ...compareOptions - 其他用于比较的选项,例如sensitivity等
* @returns {Array} 排序后的数组
*/
const numbers = [10, 2, 33];
console.log(zpyTools.sortArray(numbers)); // 输出 [2, 10, 33]
// 对一维数组进行降序排序
console.log(zpyTools.sortArray(numbers, { isDesc: true })); // [33, 10, 2]
// 对对象数组按照特定键进行升序排序
const objects = [{ name: 'Alice', age: 30 }, { name: 'Bob', age: 25 }];
console.log(zpyTools.sortArray(objects, { key: 'age' })); // [{ name: 'Bob', age: 25 }, { name: 'Alice', age: 30 }]
// 对对象数组按照特定键进行降序排序,并使用德语规则进行字符串比较
console.log(zpyTools.sortArray(objects, {
key: 'name',
isDesc: false,
locales: 'de',
compareOptions: { sensitivity: 'base' }
})); // [{ name: 'Bob', age: 25 }, { name: 'Alice', age: 30 }]
/**
* 将数组拼接成字符串
* @param {*} value - 值,可以是数组或字符串
* @param {String} [separator=","] - 分隔符,默认为逗号
* @returns {String} 拼接后的字符串
*/
console.log(zpyTools.arrayToString(["apple", "banana", "orange"])); // "apple,banana,orange"
console.log(zpyTools.arrayToString("already a string")); // "already a string"
console.log(zpyTools.arrayToString([])); // ""
console.log(zpyTools.arrayToString(null)); // ""
console.log(zpyTools.arrayToString([1, 2, 3], "-")); // "1-2-3"
/**
* 将字符串拆分成数组
* @param {*} value - 值,可以是字符串或数组
* @param {String} [separator=","] - 分隔符,默认为逗号
* @returns {Array} 拆分后的数组
*/
console.log(zpyTools.stringToArray("apple, banana, orange")); // ["apple", "banana", "orange"]
console.log(zpyTools.stringToArray(["apple", "banana", "orange"])); // ["apple", "banana", "orange"]
console.log(zpyTools.stringToArray(" apple , banana , orange ")); // ["apple", "banana", "orange"]
console.log(zpyTools.stringToArray("")); // []
console.log(zpyTools.stringToArray(null)); // []
/**
* 将扁平数组转换为树形结构
* @param {Array} items - 扁平数组,每个元素包含 id 和 parentId 属性
* @param {String} [idKey='id'] - 表示唯一标识的键名,默认为 'id'
* @param {String} [parentIdKey='parentId'] - 表示父级标识的键名,默认为 'parentId'
* @param {*} [rootValue=null] - 根节点的父级标识值,默认为 null
* @returns {Array} 转换后的树形结构数组
*/
const flatArray = [
{ id: 1, parentId: null, name: 'Root' },
{ id: 2, parentId: 1, name: 'Child 1' },
{ id: 3, parentId: 1, name: 'Child 2' },
{ id: 4, parentId: 2, name: 'Grandchild 1' }
];
console.log(zpyTools.arrayToTree(flatArray));
// [
// {
// "id": 1,
// "parentId": null,
// "name": "Root",
// "children": [
// {
// "id": 2,
// "parentId": 1,
// "name": "Child 1",
// "children": [
// {
// "id": 4,
// "parentId": 2,
// "name": "Grandchild 1",
// "children": []
// }
// ]
// },
// {
// "id": 3,
// "parentId": 1,
// "name": "Child 2",
// "children": []
// }
// ]
// }
// ]
/**
* 将树形结构转换为数组
* @param {Object} tree - 树形结构的根节点
* @param {Array} [result=[]] - 用于收集结果的数组,可选,默认为空数组
* @returns {Array} 转换后的数组
*/
const tree = {
id: 1,
name: 'root',
children: [
{ id: 2, name: 'child1', children: [] },
{ id: 3, name: 'child2', children: [{ id: 4, name: 'grandchild', children: [] }] }
]
};
console.log(zpyTools.treeToArray(tree));
// [
// {
// "id": 1,
// "name": "root",
// "children": [
// {
// "id": 2,
// "name": "child1",
// "children": []
// },
// {
// "id": 3,
// "name": "child2",
// "children": [
// {
// "id": 4,
// "name": "grandchild",
// "children": []
// }
// ]
// }
// ]
// },
// {
// "id": 2,
// "name": "child1",
// "children": []
// },
// {
// "id": 3,
// "name": "child2",
// "children": [
// {
// "id": 4,
// "name": "grandchild",
// "children": []
// }
// ]
// },
// {
// "id": 4,
// "name": "grandchild",
// "children": []
// }
// ]
/**
* 深度比较两个对象是否包含相同的值
* @param {Object} obj1 - 第一个对象
* @param {Object} obj2 - 第二个对象
* @returns {Boolean} - 如果两个对象的值完全相同,返回true,否则返回false
*/
const objA = { a: 1, b: { c: 2 } };
const objB = { a: 1, b: { c: 2 } };
console.log(zpyTools.hasObjectsEqual(objA, objB)); // true
const objC = { a: 1, b: { c: 3 } };
console.log(zpyTools.hasObjectsEqual(objA, objC)); // false
const circularA = {};
circularA.self = circularA;
const circularB = {};
circularB.self = circularB;
console.log(zpyTools.hasObjectsEqual(circularA, circularB)); // true
/**
* 防抖函数工厂
* @param {Function} fn - 需要执行的函数
* @param {Number} [delay=500] - 延迟时间,默认500ms
* @param {Boolean} [immediate=false] - 是否立即执行,默认false
* @returns {Function} 返回防抖包装后的函数
*/
const debouncedFunction = zpyTools.debounce(function () {
console.log('This will be logged after 500ms of no new calls.');
}, 500);
setInterval(debouncedFunction, 200); // 每200毫秒触发一次,但实际每500毫秒最多执行一次
// 立即执行版本示例用法:
const immediatelyDebouncedFunction = zpyTools.debounce(function () {
console.log('This will execute immediately and then wait for 500ms.');
}, 500, true);
immediatelyDebouncedFunction(); // This will execute immediately and then wait for 500ms.
/**
* 节流函数工厂
* @param {Function} fn - 需要执行的函数
* @param {Number} [interval=1000] - 间隔时间,默认1000ms
* @returns {Function} 返回节流包装后的函数
*/
const throttledFunction = zpyTools.throttle(function () {
console.log('This will be logged at most once every second.');
}, 1000);
setInterval(throttledFunction, 250); // 每250毫秒触发一次,但实际每秒最多执行一次
/**
* 获取URL中的参数
* @param {String} [url] - URL字符串,默认为当前页面的URL
* @returns {Object} 包含URL参数的对象
*/
console.log(zpyTools.getUrlParams('http://example.com/?name=John&age=30&name=Jane'));
// {
// "name": [
// "John",
// "Jane"
// ],
// "age": "30"
// }
/**
* 将参数添加到URL
* @param {string} url 基础URL
* @param {Object} params 要添加的参数对象
* @returns {string} 添加了参数后的URL
*/
console.log(zpyTools.addParamsToUrl('http://example.com', { param1: 'value1', param2: 'value2' })); // http://example.com?param1=value1¶m2=value2
/**
* 将数组按给定的属性进行分类
* @param {Array} array 需要分类的数组
* @param {String} property 用于分类的属性名
* @returns {Object} 分类结果,键为属性值,值为对应的数组
*/
const data = [
{ id: 1, category: 'fruit', name: 'apple' },
{ id: 2, category: 'vegetable', name: 'carrot' },
{ id: 3, category: 'fruit', name: 'banana' },
{ id: 4, category: 'vegetable', name: 'broccoli' },
{ id: 5, name: 'unknown' } // 缺少 category 属性
];
console.log(zpyTools.classifyBy(data, 'category'));
// {
// "fruit": [
// {
// "id": 1,
// "category": "fruit",
// "name": "apple"
// },
// {
// "id": 3,
// "category": "fruit",
// "name": "banana"
// }
// ],
// "vegetable": [
// {
// "id": 2,
// "category": "vegetable",
// "name": "carrot"
// },
// {
// "id": 4,
// "category": "vegetable",
// "name": "broccoli"
// }
// ],
// "undefined": [
// {
// "id": 5,
// "name": "unknown"
// }
// ]
// }
console.log(zpyTools.classifyBy(data, 'name'));
// {
// "apple": [
// {
// "id": 1,
// "category": "fruit",
// "name": "apple"
// }
// ],
// "carrot": [
// {
// "id": 2,
// "category": "vegetable",
// "name": "carrot"
// }
// ],
// "banana": [
// {
// "id": 3,
// "category": "fruit",
// "name": "banana"
// }
// ],
// "broccoli": [
// {
// "id": 4,
// "category": "vegetable",
// "name": "broccoli"
// }
// ],
// "unknown": [
// {
// "id": 5,
// "name": "unknown"
// }
// ]
// }
console.log(zpyTools.classifyBy([], 'category')); // {}
console.log(zpyTools.classifyBy(data, '')); // 抛出错误:The property name cannot be empty or null.
ISC