Skip to content

Commit

Permalink
Feat (number) / inRange function (#255)
Browse files Browse the repository at this point in the history
* Add inRange function

* Match with lodash inRange function

* Build cdn

* Add overloading functions

* Build cdn

---------

Co-authored-by: Ray Epps <[email protected]>
  • Loading branch information
mertdy and sodiray authored Feb 21, 2024
1 parent 32a3de4 commit 70a117b
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 2 deletions.
13 changes: 12 additions & 1 deletion cdn/radash.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,17 @@ const callable = (obj, fn) => {
});
};

function inRange(number, start, end) {
const isTypeSafe = typeof number === "number" && typeof start === "number" && (typeof end === "undefined" || typeof end === "number");
if (!isTypeSafe) {
return false;
}
if (typeof end === "undefined") {
end = start;
start = 0;
}
return number >= Math.min(start, end) && number < Math.max(start, end);
}
const toFloat = (value, defaultValue) => {
const def = defaultValue === void 0 ? 0 : defaultValue;
if (value === null || value === void 0) {
Expand Down Expand Up @@ -923,4 +934,4 @@ const trim = (str, charsToTrim = " ") => {
return str.replace(regex, "");
};

export { all, alphabetical, assign, boil, callable, camel, capitalize, chain, clone, cluster, compose, construct, counting, crush, dash, debounce, defer, diff, draw, first, flat, fork, get, group, guard, intersects, invert, isArray, isDate, isEmpty, isEqual, isFloat, isFunction, isInt, isNumber, isObject, isPrimitive, isPromise, isString, isSymbol, iterate, keys, last, list, listify, lowerize, map, mapEntries, mapKeys, mapValues, max, memo, merge, min, objectify, omit, parallel, partial, partob, pascal, pick, proxied, random, range, reduce, replace, replaceOrAppend, retry, select, series, set, shake, shift, shuffle, sift, sleep, snake, sort, sum, template, throttle, title, toFloat, toInt, toggle, trim, tryit as try, tryit, uid, unique, upperize, zip, zipToObject };
export { all, alphabetical, assign, boil, callable, camel, capitalize, chain, clone, cluster, compose, construct, counting, crush, dash, debounce, defer, diff, draw, first, flat, fork, get, group, guard, inRange, intersects, invert, isArray, isDate, isEmpty, isEqual, isFloat, isFunction, isInt, isNumber, isObject, isPrimitive, isPromise, isString, isSymbol, iterate, keys, last, list, listify, lowerize, map, mapEntries, mapKeys, mapValues, max, memo, merge, min, objectify, omit, parallel, partial, partob, pascal, pick, proxied, random, range, reduce, replace, replaceOrAppend, retry, select, series, set, shake, shift, shuffle, sift, sleep, snake, sort, sum, template, throttle, title, toFloat, toInt, toggle, trim, tryit as try, tryit, uid, unique, upperize, zip, zipToObject };
12 changes: 12 additions & 0 deletions cdn/radash.js
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,17 @@ var radash = (function (exports) {
});
};

function inRange(number, start, end) {
const isTypeSafe = typeof number === "number" && typeof start === "number" && (typeof end === "undefined" || typeof end === "number");
if (!isTypeSafe) {
return false;
}
if (typeof end === "undefined") {
end = start;
start = 0;
}
return number >= Math.min(start, end) && number < Math.max(start, end);
}
const toFloat = (value, defaultValue) => {
const def = defaultValue === void 0 ? 0 : defaultValue;
if (value === null || value === void 0) {
Expand Down Expand Up @@ -951,6 +962,7 @@ var radash = (function (exports) {
exports.get = get;
exports.group = group;
exports.guard = guard;
exports.inRange = inRange;
exports.intersects = intersects;
exports.invert = invert;
exports.isArray = isArray;
Expand Down
22 changes: 22 additions & 0 deletions docs/number/in-range.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: inRange
description: Checks if the given number is between two numbers. The starting number is inclusive. The ending number is exclusive. The start and the end of the range can be ascending OR descending order. If end is not specified, it's set to start value. And start is set to 0.
group: Number
---

## Basic usage

Pass the number, the start and the end (optional) of the range. The `_.inRange` function will return true if the given number is in the range.

```ts
import { inRange } from 'radash'

inRange(10, 0, 20) // true
inRange(9.99, 0, 10) // true
inRange(Math.PI, 0, 3.15) // true
inRange(10, 10, 20) // true
inRange(10, 0, 10) // false

inRange(1, 2) // true
inRange(1, 0) // false
```
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export {
proxied,
throttle
} from './curry'
export { toFloat, toInt } from './number'
export { inRange, toFloat, toInt } from './number'
export {
assign,
clone,
Expand Down
44 changes: 44 additions & 0 deletions src/number.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
/**
* Checks if the given number is between zero (0) and the ending number. 0 is inclusive.
*
* * Numbers can be negative or positive.
* * Ending number is exclusive.
*
* @param {number} number The number to check.
* @param {number} end The end of the range. Exclusive.
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
*/
export function inRange(number: number, end: number): boolean

/**
* Checks if the given number is between two numbers.
*
* * Numbers can be negative or positive.
* * Starting number is inclusive.
* * Ending number is exclusive.
* * The start and the end of the range can be ascending OR descending order.
*
* @param {number} number The number to check.
* @param {number} start The start of the range. Inclusive.
* @param {number} end The end of the range. Exclusive.
* @returns {boolean} Returns `true` if `number` is in the range, else `false`.
*/
export function inRange(number: number, start: number, end: number): boolean
export function inRange(number: number, start: number, end?: number): boolean {
const isTypeSafe =
typeof number === 'number' &&
typeof start === 'number' &&
(typeof end === 'undefined' || typeof end === 'number')

if (!isTypeSafe) {
return false
}

if (typeof end === 'undefined') {
end = start
start = 0
}

return number >= Math.min(start, end) && number < Math.max(start, end)
}

export const toFloat = <T extends number | null = number>(
value: any,
defaultValue?: T
Expand Down
46 changes: 46 additions & 0 deletions src/tests/number.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,51 @@ import { assert } from 'chai'
import * as _ from '..'

describe('number module', () => {
describe('inRange function', () => {
test('handles nullish values', () => {
assert.strictEqual(_.inRange(0, 1, null as any), false)
assert.strictEqual(_.inRange(0, null as any, 1), false)
assert.strictEqual(_.inRange(null as any, 0, 1), false)
assert.strictEqual(_.inRange(0, undefined as any, 1), false)
assert.strictEqual(_.inRange(undefined as any, 0, 1), false)

assert.strictEqual(_.inRange(0, 1, undefined as any), true)
})
test('handles bad input', () => {
const result = _.inRange(0, 1, {} as any)
assert.strictEqual(result, false)
})
test('computes correctly', () => {
assert.strictEqual(_.inRange(10, 0, 5), false)
assert.strictEqual(_.inRange(10, 0, 20), true)
assert.strictEqual(_.inRange(-10, 0, -20), true)
assert.strictEqual(_.inRange(9.99, 0, 10), true)
assert.strictEqual(_.inRange(Math.PI, 0, 3.15), true)
})
test('handles the different syntax of number type', () => {
assert.strictEqual(_.inRange(0, -1, 1), true)
assert.strictEqual(_.inRange(Number(0), -1, 1), true)
assert.strictEqual(_.inRange(+'0', -1, 1), true)
})
test('handles two params', () => {
assert.strictEqual(_.inRange(1, 2), true)
assert.strictEqual(_.inRange(1.2, 2), true)
assert.strictEqual(_.inRange(2, 1), false)
assert.strictEqual(_.inRange(2, 2), false)
assert.strictEqual(_.inRange(3.2, 2), false)
assert.strictEqual(_.inRange(-1, 1), false)
assert.strictEqual(_.inRange(-1, -10), true)
})
test('handles the exclusive end of the range', () => {
assert.strictEqual(_.inRange(1, 0, 1), false)
assert.strictEqual(_.inRange(10.0, 0, 10), false)
})
test('handles the inclusive start of the range', () => {
assert.strictEqual(_.inRange(0, 0, 1), true)
assert.strictEqual(_.inRange(10.0, 10, 20), true)
})
})

describe('toFloat function', () => {
test('handles null', () => {
const result = _.toFloat(null)
Expand All @@ -24,6 +69,7 @@ describe('number module', () => {
assert.strictEqual(result, 20.0)
})
})

describe('toInt function', () => {
test('handles null', () => {
const result = _.toInt(null)
Expand Down

0 comments on commit 70a117b

Please sign in to comment.