CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ramda

A practical functional library for JavaScript programmers.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

list-functions.mddocs/

List/Array Functions

Ramda provides 94 comprehensive functions for working with arrays and list-like structures. These functions follow Ramda's core principles of immutability, currying, and function-first data-last parameter order.

Core Transformation Functions

map

Transform each element of a list using a function.

/**
 * @param {Function} fn - Transformation function (a -> b)  
 * @param {Array} list - List to transform
 * @returns {Array} New list with transformed elements
 */
R.map(fn, list)

// Examples
R.map(x => x * 2, [1, 2, 3, 4]);        // => [2, 4, 6, 8]
R.map(R.toUpper, ['hello', 'world']);    // => ['HELLO', 'WORLD']
R.map(R.prop('name'), [{name: 'John'}, {name: 'Jane'}]); // => ['John', 'Jane']

// Curried usage
const double = R.map(R.multiply(2));
double([1, 2, 3]); // => [2, 4, 6]

filter

Select elements that satisfy a predicate function.

/**
 * @param {Function} predicate - Test function (a -> Boolean)
 * @param {Array} list - List to filter  
 * @returns {Array} New list with matching elements
 */
R.filter(predicate, list)

// Examples
R.filter(x => x > 5, [1, 6, 8, 2, 9]);     // => [6, 8, 9]
R.filter(R.has('active'), [{active: true}, {active: false}, {}]); // => [{active: true}, {active: false}]

const isEven = x => x % 2 === 0;
R.filter(isEven, [1, 2, 3, 4, 5, 6]);      // => [2, 4, 6]

reject

Remove elements that satisfy a predicate function (opposite of filter).

/**
 * @param {Function} predicate - Test function (a -> Boolean)
 * @param {Array} list - List to filter  
 * @returns {Array} New list with non-matching elements
 */
R.reject(predicate, list)

// Examples
R.reject(x => x > 5, [1, 6, 8, 2, 9]);     // => [1, 2]
R.reject(R.has('active'), [{active: true}, {active: false}, {}]); // => [{}]

const isOdd = x => x % 2 === 1;
R.reject(isOdd, [1, 2, 3, 4, 5, 6]);       // => [2, 4, 6]

reduce

Accumulate list elements into a single value.

/**
 * @param {Function} reducer - Accumulator function ((acc, val) -> acc)
 * @param {*} initialValue - Starting accumulator value
 * @param {Array} list - List to reduce
 * @returns {*} Final accumulated value
 */
R.reduce(reducer, initialValue, list)

// Examples
R.reduce(R.add, 0, [1, 2, 3, 4]);          // => 10
R.reduce(R.multiply, 1, [2, 3, 4]);        // => 24
R.reduce(R.max, -Infinity, [5, 2, 8, 1]);  // => 8

// Building objects
const groupBy = (key, list) => R.reduce(
  (acc, item) => R.assoc(item[key], [...(acc[item[key]] || []), item], acc),
  {},
  list
);

Search and Selection

find

Get the first element matching a predicate.

/**
 * @param {Function} predicate - Test function (a -> Boolean)
 * @param {Array} list - List to search
 * @returns {* | undefined} First matching element or undefined
 */
R.find(predicate, list)

const users = [{id: 1, name: 'John'}, {id: 2, name: 'Jane'}];
R.find(R.propEq(2, 'id'), users);          // => {id: 2, name: 'Jane'}
R.find(x => x > 10, [1, 5, 15, 3]);        // => 15

findIndex

Get the index of the first element matching a predicate.

/**
 * @param {Function} predicate - Test function (a -> Boolean)
 * @param {Array} list - List to search  
 * @returns {Number} Index of match or -1 if not found
 */
R.findIndex(predicate, list)

R.findIndex(R.equals('world'), ['hello', 'world', 'foo']); // => 1
R.findIndex(x => x > 100, [10, 50, 150, 200]); // => 2

head, tail, last, init

Access list boundaries.

// Get first element
R.head(['a', 'b', 'c']); // => 'a'
R.head([]);              // => undefined

// Get all but first element  
R.tail(['a', 'b', 'c']); // => ['b', 'c']
R.tail([]);              // => []

// Get last element
R.last(['a', 'b', 'c']); // => 'c' 
R.last([]);              // => undefined

// Get all but last element
R.init(['a', 'b', 'c']); // => ['a', 'b']
R.init([]);              // => []

nth

Access element at specific index (supports negative indices).

/**
 * @param {Number} index - Position to access
 * @param {Array} list - List to index into
 * @returns {*} Element at index or undefined
 */
R.nth(index, list)

const list = ['a', 'b', 'c', 'd'];
R.nth(1, list);     // => 'b'
R.nth(-1, list);    // => 'd' (last element)
R.nth(-2, list);    // => 'c' (second to last)
R.nth(10, list);    // => undefined

List Manipulation

append, prepend

Add elements to list boundaries.

// Add to end
R.append('new', ['a', 'b', 'c']);    // => ['a', 'b', 'c', 'new']

// Add to beginning  
R.prepend('new', ['a', 'b', 'c']);   // => ['new', 'a', 'b', 'c']

// Curried usage
const addExclamation = R.append('!');
addExclamation(['Hello', 'World']); // => ['Hello', 'World', '!']

insert, insertAll

Insert elements at specific positions.

// Insert single element
R.insert(2, 'NEW', [1, 2, 3, 4]);        // => [1, 2, 'NEW', 3, 4]

// Insert multiple elements  
R.insertAll(2, ['X', 'Y'], [1, 2, 3, 4]); // => [1, 2, 'X', 'Y', 3, 4]

remove, update

Modify list elements.

// Remove elements (start index, count)
R.remove(2, 1, [1, 2, 3, 4, 5]);        // => [1, 2, 4, 5]
R.remove(1, 3, [1, 2, 3, 4, 5]);        // => [1, 5]

// Update element at index
R.update(1, 'NEW', ['a', 'b', 'c']);     // => ['a', 'NEW', 'c']
R.update(-1, 'LAST', ['a', 'b', 'c']);   // => ['a', 'b', 'LAST']

adjust

Transform element at specific index.

/**
 * @param {Number} index - Position to modify
 * @param {Function} fn - Transformation function  
 * @param {Array} list - List to modify
 * @returns {Array} New list with element transformed
 */
R.adjust(index, fn, list)

R.adjust(1, R.toUpper, ['a', 'b', 'c']);    // => ['a', 'B', 'c']
R.adjust(-1, R.multiply(10), [1, 2, 3]);    // => [1, 2, 30]

Slicing and Partitioning

slice

Extract portion of list.

/**
 * @param {Number} from - Start index (inclusive)
 * @param {Number} to - End index (exclusive)  
 * @param {Array} list - List to slice
 * @returns {Array} Extracted portion
 */
R.slice(from, to, list)

R.slice(1, 3, [1, 2, 3, 4, 5]);          // => [2, 3]
R.slice(2, -1, [1, 2, 3, 4, 5]);         // => [3, 4]
R.slice(0, 2, 'hello');                  // => 'he'

take, takeLast, drop, dropLast

Take or drop elements from list boundaries.

// Take from start
R.take(3, [1, 2, 3, 4, 5]);              // => [1, 2, 3]
R.take(2, 'hello');                       // => 'he'

// Take from end  
R.takeLast(3, [1, 2, 3, 4, 5]);          // => [3, 4, 5]

// Drop from start
R.drop(2, [1, 2, 3, 4, 5]);              // => [3, 4, 5]

// Drop from end
R.dropLast(2, [1, 2, 3, 4, 5]);          // => [1, 2, 3]

takeWhile, dropWhile

Take/drop based on predicate.

const isLessThan5 = x => x < 5;

R.takeWhile(isLessThan5, [1, 2, 6, 7, 3]); // => [1, 2]
R.dropWhile(isLessThan5, [1, 2, 6, 7, 3]); // => [6, 7, 3]

splitAt, splitEvery

Split lists at specific points.

// Split at index
R.splitAt(2, [1, 2, 3, 4, 5]);           // => [[1, 2], [3, 4, 5]]
R.splitAt(3, 'hello');                    // => ['hel', 'lo']

// Split into chunks
R.splitEvery(2, [1, 2, 3, 4, 5, 6]);     // => [[1, 2], [3, 4], [5, 6]]
R.splitEvery(3, 'abcdefgh');              // => ['abc', 'def', 'gh']

Grouping and Aggregation

groupBy

Group elements by computed key.

/**
 * @param {Function} keyFn - Function to compute grouping key (a -> String)
 * @param {Array} list - List to group
 * @returns {Object} Object with keys mapping to arrays of elements
 */
R.groupBy(keyFn, list)

const students = [
  {name: 'Alice', grade: 'A'},
  {name: 'Bob', grade: 'B'}, 
  {name: 'Carol', grade: 'A'}
];

R.groupBy(R.prop('grade'), students);
// => {A: [{name: 'Alice', grade: 'A'}, {name: 'Carol', grade: 'A'}], 
//     B: [{name: 'Bob', grade: 'B'}]}

R.groupBy(R.length, ['cat', 'dog', 'elephant', 'ox']);
// => {'2': ['ox'], '3': ['cat', 'dog'], '8': ['elephant']}

partition

Split list into two arrays based on predicate.

/**
 * @param {Function} predicate - Test function (a -> Boolean)
 * @param {Array} list - List to partition  
 * @returns {Array} Two-element array [matching, non-matching]
 */
R.partition(predicate, list)

const isEven = x => x % 2 === 0;
R.partition(isEven, [1, 2, 3, 4, 5, 6]); // => [[2, 4, 6], [1, 3, 5]]

R.partition(R.has('active'), [{active: true}, {}, {active: false}]);
// => [[{active: true}, {active: false}], [{}]]

Combining Lists

concat

Join two lists together.

R.concat([1, 2], [3, 4]);                // => [1, 2, 3, 4]
R.concat('hello', ' world');              // => 'hello world'

// Curried
const addSuffix = R.concat(R.__, ' Inc.');
addSuffix('Acme Corp'); // => 'Acme Corp Inc.'

zip, zipWith

Combine corresponding elements from multiple lists.

// Create pairs
R.zip([1, 2, 3], ['a', 'b', 'c']);       // => [[1, 'a'], [2, 'b'], [3, 'c']]

// Combine with function
R.zipWith(R.add, [1, 2, 3], [4, 5, 6]);  // => [5, 7, 9]
R.zipWith(R.concat, ['a', 'b'], ['1', '2']); // => ['a1', 'b1']

Uniqueness and Deduplication

uniq, uniqBy, uniqWith

Remove duplicates using different equality strategies.

// Remove duplicates (R.equals)
R.uniq([1, 1, 2, 2, 3]);                 // => [1, 2, 3]
R.uniq([1, '1', 2, '2']);                 // => [1, '1', 2, '2']

// Remove duplicates by computed value
R.uniqBy(Math.abs, [-1, 1, -2, 2, 3]);   // => [-1, -2, 3]
R.uniqBy(R.prop('id'), [{id: 1, name: 'A'}, {id: 2, name: 'B'}, {id: 1, name: 'C'}]);
// => [{id: 1, name: 'A'}, {id: 2, name: 'B'}]

// Remove duplicates with custom equality
const sameLength = (a, b) => a.length === b.length;
R.uniqWith(sameLength, ['cat', 'dog', 'bat', 'fox']); // => ['cat', 'dog']

Generation Functions

range

Create array of numbers from start to end (exclusive).

/**
 * @param {Number} from - Starting number (inclusive)
 * @param {Number} to - Ending number (exclusive)
 * @returns {Array} Array of numbers
 */
R.range(from, to)

R.range(1, 5);                            // => [1, 2, 3, 4]
R.range(0, 3);                            // => [0, 1, 2]
R.range(5, 5);                            // => []

// Useful for iterations
R.map(R.multiply(2), R.range(1, 6));      // => [2, 4, 6, 8, 10]

times

Call function n times, collecting results in array.

/**
 * @param {Function} fn - Function to call with index (Number -> a)
 * @param {Number} n - Number of times to call
 * @returns {Array} Array of results
 */
R.times(fn, n)

R.times(R.identity, 5);                   // => [0, 1, 2, 3, 4]
R.times(R.always('x'), 3);                // => ['x', 'x', 'x']
R.times(x => x * x, 4);                   // => [0, 1, 4, 9]

// Generate test data
R.times(() => Math.random(), 3);          // => [0.1, 0.8, 0.3] (example)

Flattening Operations

flatten

Completely flatten nested arrays at all levels.

/**
 * @param {Array} list - Nested array to flatten
 * @returns {Array} Completely flattened array
 */
R.flatten(list)

R.flatten([1, [2, [3, [4]]]]);            // => [1, 2, 3, 4]
R.flatten([[1, 2], [3, 4], [5]]);         // => [1, 2, 3, 4, 5]
R.flatten([1, 2, 3]);                     // => [1, 2, 3] (already flat)

unnest

Remove one level of nesting (shallow flatten).

/**
 * @param {Array} list - Array to unnest one level
 * @returns {Array} Array with one level removed
 */
R.unnest(list)

R.unnest([[1, 2], [3, 4], [5]]);         // => [1, 2, 3, 4, 5]
R.unnest([1, [2, [3, 4]]]);               // => [1, 2, [3, 4]]
R.unnest([1, 2, 3]);                      // => [1, 2, 3] (no nesting)

Advanced Operations

chain (flatMap)

Map and flatten in one operation.

/**
 * @param {Function} fn - Function that returns a list (a -> [b])
 * @param {Array} list - List to map over
 * @returns {Array} Flattened result
 */
R.chain(fn, list)

const duplicate = x => [x, x];
R.chain(duplicate, [1, 2, 3]);           // => [1, 1, 2, 2, 3, 3]

R.chain(R.split(''), ['hello', 'world']); // => ['h','e','l','l','o','w','o','r','l','d']

aperture

Create sliding windows of consecutive elements.

/**
 * @param {Number} size - Window size
 * @param {Array} list - List to window
 * @returns {Array} Array of windows
 */
R.aperture(size, list)

R.aperture(2, [1, 2, 3, 4, 5]);          // => [[1,2], [2,3], [3,4], [4,5]]
R.aperture(3, [1, 2, 3, 4, 5]);          // => [[1,2,3], [2,3,4], [3,4,5]]

transpose

Flip rows and columns of 2D array.

R.transpose([[1, 'a'], [2, 'b'], [3, 'c']]);
// => [[1, 2, 3], ['a', 'b', 'c']]

R.transpose([[1, 2, 3], ['a', 'b', 'c']]);  
// => [[1, 'a'], [2, 'b'], [3, 'c']]

Validation Functions

all, any, none

Test predicates across list elements.

// All elements match
R.all(x => x > 0, [1, 2, 3]);            // => true
R.all(x => x > 0, [1, -1, 3]);           // => false

// Any element matches  
R.any(x => x > 10, [1, 15, 3]);          // => true
R.any(x => x > 10, [1, 5, 3]);           // => false

// No elements match
R.none(x => x < 0, [1, 2, 3]);           // => true  
R.none(x => x < 0, [1, -1, 3]);          // => false

includes

Check if element exists in list.

R.includes(3, [1, 2, 3, 4]);             // => true
R.includes('world', 'hello world');      // => true
R.includes({a: 1}, [{a: 1}, {b: 2}]);    // => true (deep equality)

These list functions provide the foundation for functional programming patterns in JavaScript, enabling powerful data transformations while maintaining immutability and composability.

Install with Tessl CLI

npx tessl i tessl/npm-ramda

docs

function-functions.md

index.md

list-functions.md

math-logic.md

object-functions.md

string-type.md

tile.json