范围限制
a-calc 3.x 引入了范围限制语法 [min, max],可以将计算结果限制在指定范围内,超出范围的值会被截取到边界值。
基本语法
expression | [min, max]min:最小边界值max:最大边界值
当计算结果小于 min 时返回 min,大于 max 时返回 max,否则保持不变。
基本用法
javascript
import { calc } from 'a-calc'
// 超过最大值,截取到最大值
calc('150 | [0, 100]') // '100'
// 低于最小值,截取到最小值
calc('-50 | [0, 100]') // '0'
// 在范围内,保持不变
calc('50 | [0, 100]') // '50'Ctrl+D 选择词, Ctrl+/ 注释
表达式结合
范围限制可以应用于任意复杂的表达式结果:
javascript
// 表达式结果超出范围
calc('50 + 80 | [0, 100]') // '100' (130 被截取)
calc('10 - 50 | [0, 100]') // '0' (-40 被截取)
// 乘除运算
calc('25 * 5 | [0, 100]') // '100' (125 被截取)
calc('50 / 2 | [0, 100]') // '25' (在范围内)
// 复杂表达式
calc('(a + b) * c | [0, 100]', {
a: 10, b: 20, c: 5
}) // '100' (150 被截取)结合变量
javascript
// 变量值超出范围
calc('x | [0, 100]', { x: 200 }) // '100'
calc('x | [0, 100]', { x: -50 }) // '0'
// 多变量表达式
calc('a + b | [0, 100]', { a: 80, b: 50 }) // '100'
calc('a - b | [0, 100]', { a: 30, b: 50 }) // '0'使用变量作为边界
使用 @ 前缀可以引用变量值作为范围边界:
javascript
// 使用变量作为边界
calc('150 | [@min, @max]', { min: 0, max: 100 }) // '100'
calc('-50 | [@lower, @upper]', { lower: 0, upper: 100 }) // '0'
// 动态边界
calc('value | [@min, @max]', {
value: 150,
min: 10,
max: 90
}) // '90'嵌套属性路径
支持使用点号访问嵌套对象属性:
javascript
calc('150 | [@range.min, @range.max]', {
range: { min: 0, max: 100 }
}) // '100'
calc('value | [@config.limits.min, @config.limits.max]', {
value: 50,
config: {
limits: { min: 0, max: 100 }
}
}) // '50'特殊范围
负数范围
javascript
calc('0 | [-100, -10]') // '-10' (截取到最大值)
calc('-200 | [-100, -10]') // '-100' (截取到最小值)
calc('-50 | [-100, -10]') // '-50' (在范围内)小数范围
javascript
calc('1.5 | [0, 1]') // '1'
calc('-0.5 | [0, 1]') // '0'
calc('0.5 | [0, 1]') // '0.5'
// 精确小数边界
calc('0.75 | [0.25, 0.5]') // '0.5'
calc('0.1 | [0.25, 0.5]') // '0.25'单边限制
如果只需要限制一边,可以使用极值:
javascript
// 只限制最小值(最大值设为极大)
calc('x | [0, 999999999]', { x: -10 }) // '0'
// 只限制最大值(最小值设为极小)
calc('x | [-999999999, 100]', { x: 200 }) // '100'结合其他格式化
范围限制可以与其他格式化规则组合使用:
javascript
// 范围限制 + 小数位数
calc('150.567 | [0, 100] =2') // '100.00'
calc('50.567 | [0, 100] =2') // '50.57'
// 范围限制 + 千分位
calc('15000 | [0, 10000] ,') // '10,000'
calc('5000 | [0, 10000] ,') // '5,000'
// 范围限制 + 百分比
calc('1.5 | [0, 1] %') // '100%'
calc('0.5 | [0, 1] %') // '50%'
// 范围限制 + 正号
calc('150 | [0, 100] +') // '+100'
calc('-50 | [0, 100] +') // '+0'
// 组合多个格式化
calc('15000.567 | [0, 10000] ~5=2,') // '10,000.00'Ctrl+D 选择词, Ctrl+/ 注释
与条件表达式对比
范围限制是简化版的边界检查,等价于嵌套的条件表达式:
javascript
// 使用范围限制
calc('x | [0, 100]', { x: 150 })
// 等价的条件表达式
calc('x < 0 ? 0 : (x > 100 ? 100 : x)', { x: 150 })但范围限制语法更简洁,可读性更好。
使用场景
进度条限制
javascript
// 进度值限制在 0-100%
function getProgress(current, total) {
return calc('current / total * 100 | [0, 100]', { current, total })
}
getProgress(150, 100) // '100' (不超过 100%)
getProgress(-10, 100) // '0' (不低于 0%)音量/亮度控制
javascript
// 音量限制 0-100
function setVolume(delta, currentVolume) {
return calc('current + delta | [0, 100]', {
current: currentVolume,
delta
})
}
setVolume(30, 90) // '100' (最大 100)
setVolume(-50, 30) // '0' (最小 0)评分限制
javascript
// 评分限制 1-5 星
calc('rating | [1, 5]', { rating: 0 }) // '1'
calc('rating | [1, 5]', { rating: 6 }) // '5'
calc('rating | [1, 5]', { rating: 3.5 }) // '3.5'
// 或者 0-10 分
calc('score | [0, 10]', { score: 12 }) // '10'价格保护
javascript
// 价格在最低价和最高价之间
calc('price | [@minPrice, @maxPrice]', {
price: 50,
minPrice: 99,
maxPrice: 999
}) // '99' (提升到最低价)
calc('discountPrice | [@floor, @ceiling]', {
discountPrice: 1500,
floor: 100,
ceiling: 1000
}) // '1000' (限制到最高价)输入值校验
javascript
// 年龄限制
calc('age | [0, 150]', { age: -5 }) // '0'
calc('age | [0, 150]', { age: 200 }) // '150'
// 数量限制
calc('quantity | [1, @maxStock]', {
quantity: 100,
maxStock: 50
}) // '50'注意事项
- 类型转换:边界值和结果都会转换为数字进行比较
- 精度保持:在范围内的值会保持原始精度
- 顺序重要:必须是
[min, max]格式,min 应小于 max - 变量前缀:使用变量作为边界时必须加
@前缀
javascript
// 正确
calc('x | [@min, @max]', { x: 50, min: 0, max: 100 })
// 错误 - 变量需要 @ 前缀
calc('x | [min, max]', { x: 50, min: 0, max: 100 }) // 会报错速查表
| 表达式 | 结果 | 说明 |
|---|---|---|
150 | [0, 100] | '100' | 超过最大值 |
-50 | [0, 100] | '0' | 低于最小值 |
50 | [0, 100] | '50' | 在范围内 |
x | [@min, @max] | 动态 | 使用变量边界 |
150 | [0, 100] =2 | '100.00' | 结合小数格式化 |
15000 | [0, 10000] , | '10,000' | 结合千分位 |