基于fetch和xe-utils二次封装,支持宏公式计算
npm install sh-toolsutils.calculate(expression, data?) | expression: string - 表达式字符串data?: object - 数据上下文 | any - 计算结果 | 计算表达式并返回结果,支持 {} 模板 | utils.calculate("1+2*3") → 7utils.calculate("用户{name}", {name:"张三"}) → "用户张三" |
utils.calculateLog(expression, data?) | expression: stringdata?: object | {result, log, treeLog} - 结果和日志 | 计算表达式并返回详细执行日志 | utils.calculateLog("sum([1,2,3])") → {result: 6, log: [...], treeLog: [...]} |
expr.registerFunction(name, fn, override?) | name: string\|object - 函数名或对象fn: Function - 函数实现override?: boolean - 是否覆盖 | void | 注册自定义函数 | expr.registerFunction('double', x=>x2)expr.registerFunction({square: x=>xx}) |
expr.extendOperator(symbol, config, override?) | symbol: string - 运算符config: object - 配置override?: boolean - 是否覆盖 | void | 扩展自定义运算符 | expr.extendOperator('//', {precedence:11, fn:(a,b)=>Math.floor(a/b)}) |
abs | x: number | number | 绝对值 | abs(-10) → 10 |
ceil | x: number | number | 向上取整 | ceil(3.14) → 4 |
floor | x: number | number | 向下取整 | floor(3.14) → 3 |
round | x: number | number | 四舍五入 | round(3.14) → 3 |
pow | base: number, exponent: number | number | 幂运算 | pow(2, 3) → 8 |
sqrt | x: number | number | 平方根 | sqrt(9) → 3 |
sin | x: number | number | 正弦 | sin(0) → 0 |
cos | x: number | number | 余弦 | cos(0) → 1 |
tan | x: number | number | 正切 | tan(0) → 0 |
log | x: number | number | 自然对数 | log(10) → 2.302... |
exp | x: number | number | e的幂次 | exp(1) → 2.718... |
random | min?: number, max?: number | number | 随机数 | random() → 0.123random(1,10) → 5 |
min | ...args: number[] 或 arr: number[] | number | 最小值 | min(5,2,8,1) → 1min([5,2,8,1]) → 1 |
max | ...args: number[] 或 arr: number[] | number | 最大值 | max(5,2,8,1) → 8max([5,2,8,1]) → 8 |
add | a: number, b: number | number | 加法(精确) | add(0.1, 0.2) → 0.3 |
subtract | a: number, b: number | number | 减法(精确) | subtract(0.3, 0.1) → 0.2 |
multiply | a: number, b: number | number | 乘法(精确) | multiply(0.1, 0.2) → 0.02 |
divide | a: number, b: number | number | 除法(精确) | divide(0.3, 0.1) → 3 |
toFixed | value: number, digits: number | string | 保留小数位 | toFixed(3.14159, 2) → "3.14" |
toInteger | value: any | number | 转整数 | toInteger("123") → 123toInteger(3.14) → 3 |
toNumber | value: any | number | 转数字 | toNumber("3.14") → 3.14toNumber("123") → 123 |
truncate | value: number, digits: number | number | 截断小数位 | truncate(3.14159, 2) → 3.14 |
sum | arr: number[] | number | 求和 | sum([1,2,3]) → 6 |
mean | arr: number[] | number | 平均值 | mean([1,2,3,4]) → 2.5 |
min | arr: number[] | number | 最小值 | min([5,2,8,1]) → 1 |
max | arr: number[] | number | 最大值 | max([5,2,8,1]) → 8 |
flatten | arr: any[] | any[] | 扁平化数组 | flatten([[1,2],[3,4]]) → [1,2,3,4] |
uniq | arr: any[] | any[] | 数组去重 | uniq([1,2,2,3,3,3]) → [1,2,3] |
includes | arr: any[], value: any | boolean | 包含判断 | includes([1,2,3], 2) → true |
first | arr: any[] | any | 第一个元素 | first([1,2,3]) → 1 |
last | arr: any[] | any | 最后一个元素 | last([1,2,3]) → 3 |
length | arr: any[] | number | 数组长度 | length([1,2,3,4,5]) → 5 |
slice | arr: any[], start: number, end?: number | any[] | 切片 | slice([1,2,3,4,5], 1, 3) → [2,3] |
indexOf | arr: any[], value: any, fromIndex?: number | number | 查找索引 | indexOf([1,2,3,2], 2) → 1 |
union | ...arrays: any[][] | any[] | 数组合并并去重 | union([1,2], [2,3], [3,4]) → [1,2,3,4] |
pluck | arr: object[], property: string | any[] | 提取属性值 | pluck([{id:1},{id:2},{id:3}], 'id') → [1,2,3] |
orderBy | arr: any[], field: string, order?: 'asc'\|'desc' | any[] | 排序 | orderBy([{age:30},{age:25}], 'age', 'asc') → [{age:25},{age:30}] |
groupBy | arr: any[], field: string | object | 分组 | groupBy([{type:'A'},{type:'B'},{type:'A'}], 'type') → {A:[...], B:[...]} |
countBy | arr: any[], field: string | object | 统计计数 | countBy([{type:'A'},{type:'B'},{type:'A'}], 'type') → {A:2, B:1} |
toArrayTree | arr: any[], options?: object | any[] | 转树形结构 | toArrayTree([{id:1,pid:0},{id:2,pid:1}]) → [{id:1,children:[{id:2}]}] |
toTreeArray | tree: any[], options?: object | any[] | 树形转数组 | toTreeArray([{id:1,children:[{id:2}]}]) → [{id:1,pid:0},{id:2,pid:1}] |
invoke | arr: any[], methodName: string, ...args: any[] | any[] | 调用方法 | invoke([[1,2],[3,4]], 'join', ',') → ['1,2','3,4'] |
unzip | arr: any[][] | any[][] | 解压数组 | unzip([[1,'a'],[2,'b'],[3,'c']]) → [[1,2,3],['a','b','c']] |
includeArrays | arr1: any[], arr2: any[] | boolean | 数组包含 | includeArrays([1,2,3,4], [2,3]) → true |
trim | str: string | string | 去除两端空格 | trim(' hello ') → 'hello' |
trimLeft | str: string | string | 去除左侧空格 | trimLeft(' hello') → 'hello' |
trimRight | str: string | string | 去除右侧空格 | trimRight('hello ') → 'hello' |
camelCase | str: string | string | 转驼峰命名 | camelCase('hello_world') → 'helloWorld'camelCase('hello-world') → 'helloWorld' |
kebabCase | str: string | string | 转烤串命名 | kebabCase('helloWorld') → 'hello-world'kebabCase('HelloWorld') → 'hello-world' |
startsWith | str: string, search: string | boolean | 是否以指定字符串开头 | startsWith('hello', 'he') → truestartsWith('hello', 'lo') → false |
endsWith | str: string, search: string | boolean | 是否以指定字符串结尾 | endsWith('hello', 'lo') → trueendsWith('hello', 'he') → false |
toValueString | value: any | string | 转值字符串 | toValueString(123) → '123'toValueString(null) → '' |
toNumberString | value: any, digits?: number | string | 转数字字符串 | toNumberString(3.14159, 2) → '3.14' |
now | 无 | number | 当前时间戳 | now() → 1640995200000 |
timestamp | 无 | number | 当前时间戳 | timestamp() → 1640995200000 |
toDateString | date: any, format?: string | string | 日期格式化 | toDateString(1640995200000, 'YYYY-MM-DD') → '2022-01-01' |
getYearDiff | date1: string\|number, date2: string\|number | number | 年份差 | getYearDiff('2020-01-01', '2024-01-01') → 4 |
getMonthDiff | date1: string\|number, date2: string\|number | number | 月份差 | getMonthDiff('2024-01-01', '2024-06-01') → 5 |
getDayDiff | date1: string\|number, date2: string\|number | number | 天数差 | getDayDiff('2024-01-01', '2024-01-10') → 9 |
getHourDiff | time1: string\|number, time2: string\|number | number | 小时差 | getHourDiff('2024-01-01 10:00', '2024-01-01 15:30') → 5.5 |
getMinuteDiff | time1: string\|number, time2: string\|number | number | 分钟差 | getMinuteDiff('10:30', '11:45') → 75 |
getSecondDiff | time1: string\|number, time2: string\|number | number | 秒数差 | getSecondDiff('12:00:00', '12:01:30') → 90 |
getDayOfMonth | date: string\|number | number | 当月第几天 | getDayOfMonth('2024-01-15') → 15 |
has | obj: object, key: string | boolean | 检查属性是否存在 | has({name:'John'}, 'name') → true |
get | obj: object, path: string, defaultValue?: any | any | 深度获取属性值 | get({user:{name:'John'}}, 'user.name') → 'John'get({}, 'user.name', '默认值') → '默认值' |
assign | target: object, ...sources: object[] | object | 对象属性分配 | assign({}, {a:1}, {b:2}) → {a:1,b:2} |
merge | ...objects: object[] | object | 深度合并对象 | merge({a:{x:1}}, {a:{y:2}, b:3}) → {a:{x:1,y:2},b:3} |
pick | obj: object, keys: string[] | object | 选取指定属性 | pick({name:'John',age:30,city:'NY'}, ['name','age']) → {name:'John',age:30} |
omit | obj: object, keys: string[] | object | 排除指定属性 | omit({x:1,y:2,z:3}, ['z']) → {x:1,y:2} |
isNaN | value: any | boolean | 是否是NaN | isNaN(NaN) → trueisNaN(123) → false |
isArray | value: any | boolean | 是否是数组 | isArray([1,2,3]) → trueisArray({}) → false |
isFloat | value: any | boolean | 是否是浮点数 | isFloat(3.14) → trueisFloat(3) → false |
isInteger | value: any | boolean | 是否是整数 | isInteger(3) → trueisInteger(3.14) → false |
isBoolean | value: any | boolean | 是否是布尔值 | isBoolean(true) → trueisBoolean('true') → false |
isString | value: any | boolean | 是否是字符串 | isString('hello') → trueisString(123) → false |
isNumber | value: any | boolean | 是否是数字 | isNumber(123) → trueisNumber('123') → false |
isPlainObject | value: any | boolean | 是否是纯对象 | isPlainObject({}) → trueisPlainObject([]) → false |
isDate | value: any | boolean | 是否是日期对象 | isDate(new Date()) → trueisDate('2024-01-01') → false |
isEmpty | value: any | boolean | 是否为空 | isEmpty([]) → trueisEmpty({}) → trueisEmpty('') → trueisEmpty([1]) → false |
isNull | value: any | boolean | 是否是null | isNull(null) → trueisNull(undefined) → false |
isMatch | obj: object, source: object | boolean | 是否部分匹配 | isMatch({a:1,b:2,c:3}, {a:1,b:2}) → true |
isEqual | value1: any, value2: any | boolean | 深度相等比较 | isEqual({a:[1,2]}, {a:[1,2]}) → trueisEqual({a:1}, {a:1,b:2}) → false |
getSize | value: any | number | 获取大小 | getSize([1,2,3]) → 3getSize({a:1,b:2}) → 2getSize('hello') → 5 |
first | arr: any[] 或 ...args: any[] | any | 第一个元素 | first([1,2,3]) → 1first(1,2,3) → 1 |
last | arr: any[] 或 ...args: any[] | any | 最后一个元素 | last([1,2,3]) → 3last(1,2,3) → 3 |
javascript
import { utils } from 'sh-tools'
// 数学计算
utils.calculate("abs(-10) + pow(2, 3)") // 18
// 数组操作
utils.calculate("sum([1,2,3,4,5]) / length([1,2,3,4,5])") // 3
// 字符串处理
utils.calculate("trim(' hello ') + ' ' + camelCase('world_test')") // "hello worldTest"
// 日期计算
utils.calculate("getDayDiff('2024-01-01', '2024-01-10') + getHourDiff('10:00', '12:30')") // 12.5
// 对象操作
utils.calculate("merge({a:1}, {b:2}, {c:3})") // {a:1, b:2, c:3}
``