Skip to content

Commit

Permalink
feat: add clamp function
Browse files Browse the repository at this point in the history
  • Loading branch information
aleclarson committed Jul 12, 2024
1 parent bcdaf5d commit 55c5f19
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 0 deletions.
10 changes: 10 additions & 0 deletions benchmarks/number/clamp.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as _ from 'radashi'
import { bench } from 'vitest'

describe('clamp', () => {
bench('with no arguments', () => {
_.clamp(100, 0, 10)
_.clamp(0, 10, 100)
_.clamp(5, 0, 10)
})
})
27 changes: 27 additions & 0 deletions docs/number/clamp.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: clamp
description: Limit the range of a variable number
---

### Usage

The `clamp` function restricts a number to be within a specified
range.

- It takes three arguments: the number to clamp, the minimum value,
and the maximum value.
- If the number is less than the minimum, it returns the minimum.
- If the number is greater than the maximum, it returns the
maximum.
- Otherwise, it returns the number itself.

```ts
import * as _ from 'radashi'

_.clamp(5, 1, 10) // returns 5
_.clamp(0, 1, 10) // returns 1
_.clamp(15, 1, 10) // returns 10

// Invalid range
_.clamp(1, 10, 1) // throws
```
1 change: 1 addition & 0 deletions src/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export * from './curry/partob.ts'
export * from './curry/proxied.ts'
export * from './curry/throttle.ts'

export * from './number/clamp.ts'
export * from './number/inRange.ts'
export * from './number/lerp.ts'
export * from './number/max.ts'
Expand Down
29 changes: 29 additions & 0 deletions src/number/clamp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* The `clamp` function restricts a number to be within a specified
* range.
*
* - It takes three arguments: the number to clamp, the minimum value,
* and the maximum value.
* - If the number is less than the minimum, it returns the minimum.
* - If the number is greater than the maximum, it returns the
* maximum.
* - Otherwise, it returns the number itself.
*
* @see https://radashi-org.github.io/reference/number/clamp
* @example
* ```ts
* clamp(5, 1, 10) // returns 5
* clamp(0, 1, 10) // returns 1
* clamp(15, 1, 10) // returns 10
* ```
*/
export function clamp(
n: number,
min: number | null | undefined,
max: number | null | undefined,
): number {
if (max != null && min != null && min > max) {
throw new Error('invalid clamp range')
}
return max != null && n > max ? max : min != null && n < min ? min : n
}
35 changes: 35 additions & 0 deletions tests/number/clamp.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as _ from 'radashi'

describe('clamp', () => {
test('clamps a number within the given range', () => {
expect(_.clamp(5, 1, 10)).toBe(5)
expect(_.clamp(0, 1, 10)).toBe(1)
expect(_.clamp(15, 1, 10)).toBe(10)
})
test('handles min being null or undefined', () => {
expect(_.clamp(5, null, 10)).toBe(5)
expect(_.clamp(15, null, 10)).toBe(10)
expect(_.clamp(5, undefined, 10)).toBe(5)
expect(_.clamp(15, undefined, 10)).toBe(10)
})
test('handles max being null or undefined', () => {
expect(_.clamp(5, 1, null)).toBe(5)
expect(_.clamp(0, 1, null)).toBe(1)
expect(_.clamp(5, 1, undefined)).toBe(5)
expect(_.clamp(0, 1, undefined)).toBe(1)
})
test('handles both min and max being null or undefined', () => {
expect(_.clamp(5, null, null)).toBe(5)
expect(_.clamp(5, undefined, undefined)).toBe(5)
expect(_.clamp(-10, null, undefined)).toBe(-10)
expect(_.clamp(100, undefined, null)).toBe(100)
})
test('handles edge cases', () => {
expect(_.clamp(Number.POSITIVE_INFINITY, 1, 10)).toBe(10)
expect(_.clamp(Number.NEGATIVE_INFINITY, 1, 10)).toBe(1)
expect(_.clamp(Number.NaN, 1, 10)).toBe(Number.NaN)
})
test('throw on invalid range', () => {
expect(() => _.clamp(5, 10, 1)).toThrow('invalid clamp range')
})
})

0 comments on commit 55c5f19

Please sign in to comment.