# proto-plus-lite
A comprehensive, lightweight utility library with 43+ array and string manipulation functions for JavaScript.
## Recent changes (v1.0.5)
- Treat numeric strings as numbers in `sum()` (e.g. `sum([1, "1", 2])` now returns `4`).
- Updated README and prepared package for publishing.
## Installation
```bash
npm install proto-plus-lite
```
## Usage
### Method 1: Import Functions
Import the functions you need:
```javascript
const {
rotateLeft,
rotateRight,
uniqueFast,
capitalize,
camelCase,
// ... and more
} = require("proto-plus-lite");
// Use as regular functions
const result = rotateLeft([1, 2, 3], 1); // [2, 3, 1]
const capitalized = capitalize("hello"); // "Hello"
```
### Method 2: Extend Prototypes (Optional)
To extend Array and String prototypes with convenience methods:
```javascript
// This extends Array.prototype and String.prototype
require("proto-plus-lite");
// Use as methods
const result = [1, 2, 3].rotateLeft(1); // [2, 3, 1]
const capitalized = "hello".capitalize(); // "Hello"
const reversed = "hello".reverse(); // "olleh"
```
---
## Array Utilities
### rotateLeft(arr, k)
Rotates array elements to the left by `k` positions.
```javascript
rotateLeft([1, 2, 3, 4, 5], 2); // [3, 4, 5, 1, 2]
rotateLeft(["a", "b", "c"], 1); // ["b", "c", "a"]
```
### rotateRight(arr, k)
Rotates array elements to the right by `k` positions.
```javascript
rotateRight([1, 2, 3, 4, 5], 2); // [4, 5, 1, 2, 3]
rotateRight(["x", "y", "z"], 1); // ["z", "x", "y"]
```
### uniqueFast(arr)
Returns array with unique elements using Set.
```javascript
uniqueFast([1, 2, 2, 3, 3, 3]); // [1, 2, 3]
uniqueFast(["a", "b", "a", "c"]); // ["a", "b", "c"]
```
### chunk(arr, size)
Breaks an array into chunks of specified size.
```javascript
chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]
chunk(["a", "b", "c", "d"], 2); // [["a", "b"], ["c", "d"]]
```
### flatten(arr, depth)
Flattens nested arrays up to specified depth (default: 1).
```javascript
flatten(
[
[1, 2],
[3, 4],
],
1,
); // [1, 2, 3, 4]
flatten([[[1, 2]], [[3, 4]]], 2); // [1, 2, 3, 4]
flatten([1, [2, [3, [4]]]], 1); // [1, 2, [3, [4]]]
```
### shuffle(arr)
Randomly shuffles array elements using Fisher-Yates algorithm.
```javascript
shuffle([1, 2, 3, 4, 5]); // e.g., [3, 1, 5, 2, 4]
shuffle(["a", "b", "c"]); // e.g., ["c", "a", "b"]
```
### intersection(...arrays)
Returns elements common to all arrays.
```javascript
intersection([1, 2, 3], [2, 3, 4], [2, 3, 5]); // [2, 3]
intersection(["a", "b"], ["b", "c"], ["b", "d"]); // ["b"]
```
### difference(arr, ...arrays)
Returns elements in first array not found in other arrays.
```javascript
difference([1, 2, 3, 4], [2, 4]); // [1, 3]
difference(["a", "b", "c"], ["b"]); // ["a", "c"]
```
### compact(arr)
Removes falsy values (null, undefined, false, 0, "").
```javascript
compact([1, 0, false, 2, null, "test", ""]); // [1, 2, "test"]
compact([null, undefined, "hello", 0]); // ["hello"]
```
### reverse(arr)
Returns reversed array copy without mutating original.
```javascript
reverse([1, 2, 3]); // [3, 2, 1]
reverse(["a", "b", "c"]); // ["c", "b", "a"]
```
### findIndex(arr, element)
Returns first index of element (-1 if not found).
```javascript
findIndex([10, 20, 30], 20); // 1
findIndex(["x", "y", "z"], "z"); // 2
findIndex([1, 2, 3], 5); // -1
```
### sum(arr)
Calculates sum of numeric elements.
```javascript
sum([1, 2, 3, 4, 5]); // 15
sum([10, 20, 30]); // 60
sum([1, "text", 3]); // 4 (skips non-numeric)
```
### average(arr)
Calculates average of numeric elements.
```javascript
average([2, 4, 6]); // 4
average([10, 20, 30]); // 20
average([1, 2, 3, 4]); // 2.5
```
### max(arr)
Returns maximum value in array.
```javascript
max([3, 1, 4, 1, 5]); // 5
max([-10, -5, 0, 5]); // 5
max([100]); // 100
```
### min(arr)
Returns minimum value in array.
````javascript
min([3, 1, 4, 1, 5]); // 1
min([-10, -5, 0, 5]); // -10
min([100]); // 100
### nthMax(arr, n)
Returns the nth maximum distinct numeric value from an array (1-based). Non-numeric values are ignored.
```javascript
nthMax([5, 1, 3, 5], 1); // 5 (max)
nthMax([5, 1, 3, 5], 2); // 3 (2nd distinct max)
nthMax([1, 1, 1], 2); // undefined (not enough distinct numbers)
```
### nthMin(arr, n)
Returns the nth minimum distinct numeric value from an array (1-based). Non-numeric values are ignored.
```javascript
nthMin([5, 1, 3, 5], 1); // 1 (min)
nthMin([5, 1, 3, 5], 2); // 3 (2nd distinct min)
nthMin([7], 2); // undefined (not enough distinct numbers)
```
````
---
## String Utilities
### capitalize(str)
Capitalizes first letter of string.
```javascript
capitalize("hello"); // "Hello"
capitalize("hELLO"); // "HELLO"
capitalize("world"); // "World"
```
### camelCase(str)
Converts string to camelCase.
```javascript
camelCase("hello world"); // "helloWorld"
camelCase("hello-world"); // "helloWorld"
camelCase("hello_world"); // "helloWorld"
```
### snakeCase(str)
Converts string to snake_case.
```javascript
snakeCase("Hello World"); // "hello_world"
snakeCase("helloWorld"); // "hello_world"
snakeCase("hello-world"); // "hello_world"
```
### reverse(str)
Reverses a string.
```javascript
reverse("hello"); // "olleh"
reverse("JavaScript"); // "tpircSavaJ"
reverse("12345"); // "54321"
```
### isPalindrome(str)
Checks if string is palindrome (ignoring spaces and case).
```javascript
isPalindrome("racecar"); // true
isPalindrome("A man a plan a canal Panama"); // true
isPalindrome("hello"); // false
```
### maskMiddle(str)
Masks middle characters of string with asterisks.
```javascript
maskMiddle("hello"); // "h***o"
maskMiddle("password123"); // "p*********3"
maskMiddle("ab"); // "ab"
```
### trim(str)
Removes leading and trailing whitespace.
```javascript
trim(" hello "); // "hello"
trim("\nhello\n"); // "hello"
trim(" world "); // "world"
```
### padStart(str, length, char)
Pads string from start to reach specified length.
```javascript
padStart("5", 3, "0"); // "005"
padStart("hello", 8, "*"); // "***hello"
padStart("test", 6, "-"); // "--test"
```
### padEnd(str, length, char)
Pads string from end to reach specified length.
````javascript
padEnd("5", 3, "0"); // "500"
padEnd("hello", 8, "*"); // "hello***"
padEnd("test", 6, "-"); // "test--"
### padStartStrict(str, n, char)
Strict padStart truncates the left side of the original so the returned string length equals the original length.
```javascript
padStartStrict('hello', 3, '*'); // '***lo'
padStartStrict('hello', 5, '*'); // '*****'
padStartStrict('hello', 0, '*'); // 'hello'
````
### padEndStrict(str, n, char)
Strict padEnd truncates the right side of the original so the returned string length equals the original length.
```javascript
padEndStrict("hello", 3, "*"); // 'he***'
padEndStrict("hello", 5, "*"); // '*****'
padEndStrict("hello", 0, "*"); // 'hello'
```
````
### repeat(str, count)
Repeats string specified number of times.
```javascript
repeat("abc", 3); // "abcabcabc"
repeat("*", 5); // "*****"
repeat("ha", 4); // "hahahaha"
````
### truncate(str, length, suffix)
Truncates string and adds suffix (default: "...").
```javascript
truncate("Hello World", 8); // "Hello..."
truncate("JavaScript", 6, ">>"); // "Java>>"
truncate("test", 10); // "test" (no truncation if shorter)
```
### wordCount(str)
Counts words in string.
```javascript
wordCount("hello world"); // 2
wordCount("one two three four"); // 4
wordCount(""); // 0
```
### includes(str, substring)
Checks if string contains substring.
```javascript
includes("hello world", "world"); // true
includes("JavaScript", "Script"); // true
includes("test", "xyz"); // false
```
---
## Prototype Extension Examples
When you import the library with `require("proto-plus-lite")`, all methods are available as prototype methods:
### Array Prototype Methods
```javascript
require("proto-plus-lite");
[1, 2, 3, 4, 5].rotateLeft(2); // [3, 4, 5, 1, 2]
[1, 2, 3, 4, 5].rotateRight(1); // [5, 1, 2, 3, 4]
[1, 1, 2, 2, 3].unique(); // [1, 2, 3]
[1, 2, 3, 4, 5].chunk(2); // [[1, 2], [3, 4], [5]]
[
[1, 2],
[3, [4, 5]],
].flatten(2); // [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5].shuffle(); // randomized array
[1, 2, 3].intersection([2, 3, 4]); // [2, 3]
[1, 2, 3, 4].difference([2, 4]); // [1, 3]
[1, 0, false, 2, null].compact(); // [1, 2]
[1, 2, 3].reverse(); // [3, 2, 1]
[10, 20, 30].findIndex(20); // 1
[1, 2, 3, 4, 5].sum(); // 15
[2, 4, 6].average(); // 4
[3, 1, 4, 1, 5].max(); // 5
[3, 1, 4, 1, 5].min(); // 1
```
### String Prototype Methods
```javascript
require("proto-plus-lite");
"hello".capitalize(); // "Hello"
"hello world".camelCase(); // "helloWorld"
"hello_world".snakeCase(); // "hello_world"
"hello".reverse(); // "olleh"
"racecar".isPalindrome(); // true
"password123".maskMiddle(); // "p*********3"
" hello ".trim(); // "hello"
"5".padStart(3, "0"); // "005"
"hello".padEnd(8, "*"); // "hello***"
"ha".repeat(3); // "hahaha"
"Hello World".truncate(8); // "Hello..."
"one two three".wordCount(); // 3
"hello world".includes("world"); // true
```
---
## Error Handling
All functions include input validation and throw `TypeError` for invalid inputs:
```javascript
try {
rotateLeft("not an array", 2);
} catch (error) {
console.log(error.message); // "Invalid input: arr must be an array..."
}
try {
capitalize(123);
} catch (error) {
console.log(error.message); // "Input must be a string."
}
```
---
## License
MIT - Free for personal and commercial use