Remeda
GitHub

Adds two numbers.

Data First

R.add(value, addend);
R.add(10, 5); // => 15
R.add(10, -5); // => 5
R.reduce([1, 2, 3, 4], R.add, 0); // => 10

Data Last

R.add(addend)(value);
R.add(5)(10); // => 15
R.add(-5)(10); // => 5
R.map([1, 2, 3, 4], R.add(1)); // => [2, 3, 4, 5]

Rounds up a given number to a specific precision. If you'd like to round up to an integer (i.e. use this function with constant precision === 0), use Math.ceil instead, as it won't incur the additional library overhead.

Data First

R.ceil(value, precision);
R.ceil(123.9876, 3); // => 123.988
R.ceil(483.22243, 1); // => 483.3
R.ceil(8541, -1); // => 8550
R.ceil(456789, -3); // => 457000

Data Last

R.ceil(precision)(value);
R.ceil(3)(123.9876); // => 123.988
R.ceil(1)(483.22243); // => 483.3
R.ceil(-1)(8541); // => 8550
R.ceil(-3)(456789); // => 457000

Clamp the given value within the inclusive min and max bounds.

Data First

R.clamp(value, { min, max });
clamp(10, { min: 20 }); // => 20
clamp(10, { max: 5 }); // => 5
clamp(10, { max: 20, min: 5 }); // => 10

Data Last

R.clamp({ min, max })(value);
clamp({ min: 20 })(10); // => 20
clamp({ max: 5 })(10); // => 5
clamp({ max: 20, min: 5 })(10); // => 10

Divides two numbers.

Data First

R.divide(value, divisor);
R.divide(12, 3); // => 4
R.reduce([1, 2, 3, 4], R.divide, 24); // => 1

Data Last

R.divide(divisor)(value);
R.divide(3)(12); // => 4
R.map([2, 4, 6, 8], R.divide(2)); // => [1, 2, 3, 4]

Rounds down a given number to a specific precision. If you'd like to round down to an integer (i.e. use this function with constant precision === 0), use Math.floor instead, as it won't incur the additional library overhead.

Data First

R.floor(value, precision);
R.floor(123.9876, 3); // => 123.987
R.floor(483.22243, 1); // => 483.2
R.floor(8541, -1); // => 8540
R.floor(456789, -3); // => 456000

Data Last

R.floor(precision)(value);
R.floor(3)(123.9876); // => 123.987
R.floor(1)(483.22243); // => 483.2
R.floor(-1)(8541); // => 8540
R.floor(-3)(456789); // => 456000

multiply

Number
View source on GitHub

Multiplies two numbers.

Data First

R.multiply(value, multiplicand);
R.multiply(3, 4); // => 12
R.reduce([1, 2, 3, 4], R.multiply, 1); // => 24

Data Last

R.multiply(multiplicand)(value);
R.multiply(4)(3); // => 12
R.map([1, 2, 3, 4], R.multiply(2)); // => [2, 4, 6, 8]

Compute the product of the numbers in the array, or return 1 for an empty array.

Data First

R.product(data);
R.product([1, 2, 3]); // => 6
R.product([]); // => 1

Data Last

R.product()(data);
R.pipe([1, 2, 3], R.product()); // => 6
R.pipe([], R.product()); // => 0

Rounds a given number to a specific precision. If you'd like to round to an integer (i.e. use this function with constant precision === 0), use Math.round instead, as it won't incur the additional library overhead.

Data First

R.round(value, precision);
R.round(123.9876, 3); // => 123.988
R.round(483.22243, 1); // => 483.2
R.round(8541, -1); // => 8540
R.round(456789, -3); // => 457000

Data Last

R.round(precision)(value);
R.round(3)(123.9876); // => 123.988
R.round(1)(483.22243); // => 483.2
R.round(-1)(8541); // => 8540
R.round(-3)(456789); // => 457000

subtract

Number
View source on GitHub

Subtracts two numbers.

Data First

R.subtract(value, subtrahend);
R.subtract(10, 5); // => 5
R.subtract(10, -5); // => 15
R.reduce([1, 2, 3, 4], R.subtract, 20); // => 10

Data Last

R.subtract(subtrahend)(value);
R.subtract(5)(10); // => 5
R.subtract(-5)(10); // => 15
R.map([1, 2, 3, 4], R.subtract(1)); // => [0, 1, 2, 3]

Sums the numbers in the array, or return 0 for an empty array.

Data First

R.sum(data);
R.sum([1, 2, 3]); // => 6
R.sum([]); // => 0

Data Last

R.sum()(data);
R.pipe([1, 2, 3], R.sum()); // => 6
R.pipe([], R.sum()); // => 0

Add a new property to an object.

Data First

R.addProp(obj, prop, value);
R.addProp({ firstName: "john" }, "lastName", "doe"); // => {firstName: 'john', lastName: 'doe'}

Data Last

R.addProp(prop, value)(obj);
R.addProp("lastName", "doe")({ firstName: "john" }); // => {firstName: 'john', lastName: 'doe'}

Creates a deep copy of the value. Supported types: Array, Object, Number, String, Boolean, Date, RegExp. Functions are assigned by reference rather than copied.

R.clone(value);

entries

Object
strict
View source on GitHub

Returns an array of key/values of the enumerable properties of an object.

Data First

R.entries(object);
R.entries.strict(object);
R.entries({ a: 1, b: 2, c: 3 }); // => [['a', 1], ['b', 2], ['c', 3]]
R.entries.strict({ a: 1 } as const); // => [['a', 1]] typed Array<['a', 1]>

Data Last

R.entries()(object);
R.entries.strict()(object);
R.pipe({ a: 1, b: 2, c: 3 }, entries()); // => [['a', 1], ['b', 2], ['c', 3]]
R.pipe({ a: 1 } as const, entries.strict()); // => [['a', 1]] typed Array<['a', 1]>

Creates a new object by applying functions that is included in evolver object parameter to the data object parameter according to their corresponding path.

Functions included in evolver object will not be invoked if its corresponding key does not exist in the data object. Also, values included in data object will be kept as is if its corresponding key does not exist in the evolver object.

Data First

R.evolve(data, evolver);
const evolver = {
  count: add(1),
  time: { elapsed: add(1), remaining: add(-1) },
};
const data = {
  id: 10,
  count: 10,
  time: { elapsed: 100, remaining: 1400 },
};
evolve(data, evolver);
// => {
//   id: 10,
//   count: 11,
//   time: { elapsed: 101, remaining: 1399 },
// }

Data Last

R.evolve(evolver)(data);
const evolver = {
  count: add(1),
  time: { elapsed: add(1), remaining: add(-1) },
};
const data = {
  id: 10,
  count: 10,
  time: { elapsed: 100, remaining: 1400 },
};
R.pipe(object, R.evolve(evolver));
// => {
//   id: 10,
//   count: 11,
//   time: { elapsed: 101, remaining: 1399 },
// }

forEachObj

Object
View source on GitHub

Iterate an object using a defined callback function. The original object is returned.

Data First

R.forEachObj(object, fn);
R.forEachObj({ a: 1 }, (val) => {
  console.log(`${val}`);
}); // "1"
R.forEachObj.indexed({ a: 1 }, (val, key, obj) => {
  console.log(`${key}: ${val}`);
}); // "a: 1"

Data Last

R.forEachObj(fn)(object);
R.pipe(
  { a: 1 },
  R.forEachObj((val) => console.log(`${val}`)),
); // "1"
R.pipe(
  { a: 1 },
  R.forEachObj.indexed((val, key) => console.log(`${key}: ${val}`)),
); // "a: 1"

fromEntries

Object
strict
View source on GitHub

Creates a new object from an array of tuples by pairing up first and second elements as {[key]: value}. If a tuple is not supplied for any element in the array, the element will be ignored If duplicate keys exist, the tuple with the greatest index in the input array will be preferred.

The strict option supports more sophisticated use-cases like those that would result when calling the strict toPairs function.

There are several other functions that could be used to build an object from an array:

  • fromKeys - Builds an object from an array of keys and a mapper for values.
  • indexBy - Builds an object from an array of values and a mapper for keys.
  • pullObject - Builds an object from an array of items with mappers for both keys and values.
  • mapToObj - Builds an object from an array of items and a single mapper for key-value pairs. Refer to the docs for more details.

Data First

R.fromEntries(tuples);
R.fromEntries.strict(tuples);
R.fromEntries([
  ["a", "b"],
  ["c", "d"],
]); // => {a: 'b', c: 'd'} (type: Record<string, string>)
R.fromEntries.strict(["a", 1] as const); // => {a: 1} (type: {a: 1})

Data Last

R.fromEntries()(tuples);
R.fromEntries.strict()(tuples);
R.pipe(
  [
    ["a", "b"],
    ["c", "d"],
  ],
  R.fromEntries(),
); // => {a: 'b', c: 'd'} (type: Record<string, string>)
R.pipe(["a", 1] as const, R.fromEntries.strict()); // => {a: 1} (type: {a: 1})

fromKeys

Object
View source on GitHub

Creates an object that maps each key in data to the result of mapper for that key. Duplicate keys are overwritten, guaranteeing that mapper is run for each item in data.

There are several other functions that could be used to build an object from an array:

  • indexBy - Builds an object from an array of values and a mapper for keys.
  • pullObject - Builds an object from an array of items with mappers for both keys and values.
  • fromEntries - Builds an object from an array of key-value pairs.
  • mapToObj - Builds an object from an array of items and a single mapper for key-value pairs. Refer to the docs for more details.

Data First

R.fromKeys(data, mapper);
R.fromKeys(["cat", "dog"], R.length()); // { cat: 3, dog: 3 } (typed as Partial<Record<"cat" | "dog", number>>)
R.fromKeys([1, 2], R.add(1)); // { 1: 2, 2: 3 } (typed as Partial<Record<1 | 2, number>>)

Data Last

R.fromKeys(mapper)(data);
R.pipe(["cat", "dog"], R.fromKeys(R.length())); // { cat: 3, dog: 3 } (typed as Partial<Record<"cat" | "dog", number>>)
R.pipe([1, 2], R.fromKeys(R.add(1))); // { 1: 2, 2: 3 } (typed as Partial<Record<1 | 2, number>>)

invert

Object
pipeable
View source on GitHub

Returns an object whose keys and values are swapped. If the object contains duplicate values, subsequent values will overwrite previous values.

Data First

R.invert(object);
R.invert({ a: "d", b: "e", c: "f" }); // => { d: "a", e: "b", f: "c" }

Data Last

R.invert()(object);
R.pipe({ a: "d", b: "e", c: "f" }, R.invert()); // => { d: "a", e: "b", f: "c" }

keys

Object
pipeable
strict
View source on GitHub

Returns a new array containing the keys of the array or object.

Data First

R.keys(source);
R.keys.strict(source);
R.keys(["x", "y", "z"]); // => ['0', '1', '2']
R.keys({ a: "x", b: "y", c: "z" }); // => ['a', 'b', 'c']
R.keys.strict({ a: "x", b: "y", 5: "z" } as const); // => ['a', 'b', '5'], typed Array<'a' | 'b' | '5'>
R.pipe(["x", "y", "z"], R.keys); // => ['0', '1', '2']
R.pipe({ a: "x", b: "y", c: "z" }, R.keys); // => ['a', 'b', 'c']
R.pipe({ a: "x", b: "y", c: "z" }, R.keys, R.first()); // => 'a'
R.pipe({ a: "x", b: "y", 5: "z" } as const, R.keys.strict); // => ['a', 'b', '5'], typed Array<'a' | 'b' | '5'>

Maps keys of object and keeps the same values.

Data First

R.mapKeys(object, fn);
R.mapKeys({ a: 1, b: 2 }, (key, value) => key + value); // => { a1: 1, b2: 2 }

Data Last

R.mapKeys(fn)(object);
R.pipe(
  { a: 1, b: 2 },
  R.mapKeys((key, value) => key + value),
); // => { a1: 1, b2: 2 }

mapValues

Object
View source on GitHub

Maps values of object and keeps the same keys.

Data First

R.mapValues(object, fn);
R.mapValues({ a: 1, b: 2 }, (value, key) => value + key); // => {a: '1a', b: '2b'}

Data Last

R.mapValues(fn)(object);
R.pipe(
  { a: 1, b: 2 },
  R.mapValues((value, key) => value + key),
); // => {a: '1a', b: '2b'}

Merges two objects into one by combining their properties, effectively creating a new object that incorporates elements from both. The merge operation prioritizes the second object's properties, allowing them to overwrite those from the first object with the same names.

Equivalent to { ...data, ...source }.

Data First

R.merge(data, source);
R.merge({ x: 1, y: 2 }, { y: 10, z: 2 }); // => { x: 1, y: 10, z: 2 }

Data Last

R.merge(source)(data);
R.pipe({ x: 1, y: 2 }, R.merge({ y: 10, z: 2 })); // => { x: 1, y: 10, z: 2 }

mergeDeep

Object
View source on GitHub

Merges the source object into the destination object. The merge is similar to performing { ...destination, ... source } (where disjoint values from each object would be copied as-is, and for any overlapping props the value from source would be used); But for each prop (p), if both destination and source have a plain-object as a value, the value would be taken as the result of recursively deepMerging them (result.p === deepMerge(destination.p, source.p)).

Data First

R.mergeDeep(destination, source);
R.mergeDeep({ foo: "bar", x: 1 }, { foo: "baz", y: 2 }); // => { foo: 'baz', x: 1, y: 2 }

Data Last

R.mergeDeep(source)(destination);
R.pipe({ foo: "bar", x: 1 }, R.mergeDeep({ foo: "baz", y: 2 })); // => { foo: 'baz', x: 1, y: 2 }

Creates an object containing a single key:value pair.

R.objOf(value, key);
R.objOf(10, "a"); // => { a: 10 }
R.objOf(key)(value);
R.pipe(10, R.objOf("a")); // => { a: 10 }

Returns a partial copy of an object omitting the keys specified.

Data Last

R.omit(names)(obj);
R.pipe({ a: 1, b: 2, c: 3, d: 4 }, R.omit(["a", "d"])); // => { b: 2, c: 3 }

Data First

R.omit(obj, names);
R.omit({ a: 1, b: 2, c: 3, d: 4 }, ["a", "d"]); // => { b: 2, c: 3 }

Returns a partial copy of an object omitting the keys matching predicate.

Data First

R.omitBy(object, fn);
R.omitBy({ a: 1, b: 2, A: 3, B: 4 }, (val, key) => key.toUpperCase() === key); // => {a: 1, b: 2}

Data Last

R.omitBy(fn)(object);
R.omitBy((val, key) => key.toUpperCase() === key)({ a: 1, b: 2, A: 3, B: 4 }); // => {a: 1, b: 2}

Gets the value at path of object. If the resolved value is null or undefined, the defaultValue is returned in its place.

Data First

R.pathOr(object, array, defaultValue);
R.pathOr({ x: 10 }, ["y"], 2); // 2
R.pathOr({ y: 10 }, ["y"], 2); // 10

Data Last

R.pathOr(array, defaultValue)(object);
R.pipe({ x: 10 }, R.pathOr(["y"], 2)); // 2
R.pipe({ y: 10 }, R.pathOr(["y"], 2)); // 10

Creates an object composed of the picked object properties.

Data Last

R.pick([prop1, prop2])(object);
R.pipe({ a: 1, b: 2, c: 3, d: 4 }, R.pick(["a", "d"])); // => { a: 1, d: 4 }

Data First

R.pick(object, [prop1, prop2]);
R.pick({ a: 1, b: 2, c: 3, d: 4 }, ["a", "d"]); // => { a: 1, d: 4 }

Creates an object composed of the picked object properties.

Data First

R.pickBy(object, fn);
R.pickBy({ a: 1, b: 2, A: 3, B: 4 }, (val, key) => key.toUpperCase() === key); // => {A: 3, B: 4}

Data Last

R.pickBy(fn)(object);
R.pickBy((val, key) => key.toUpperCase() === key)({ a: 1, b: 2, A: 3, B: 4 }); // => {A: 3, B: 4}

Gets the value of the given property.

Data Last

R.prop(prop)(object);
R.pipe({ foo: "bar" }, R.prop("foo")); // => 'bar'

pullObject

Object
View source on GitHub

Creates an object that maps the result of valueExtractor with a key resulting from running keyExtractor on each item in data. Duplicate keys are overwritten, guaranteeing that the extractor functions are run on each item in data.

There are several other functions that could be used to build an object from an array:

  • fromKeys - Builds an object from an array of keys and a mapper for values.
  • indexBy - Builds an object from an array of values and a mapper for keys.
  • fromEntries - Builds an object from an array of key-value pairs.
  • mapToObj - Builds an object from an array of items and a single mapper for key-value pairs. Refer to the docs for more details.

Data First

R.pullObject(data, keyExtractor, valueExtractor);
R.pullObject(
  [
    { name: "john", email: "john@remedajs.com" },
    { name: "jane", email: "jane@remedajs.com" },
  ],
  R.prop("name"),
  R.prop("email"),
); // => { john: "john@remedajs.com", jane: "jane@remedajs.com" }

Data Last

R.pullObject(keyExtractor, valueExtractor)(data);
R.pipe(
  [
    { name: "john", email: "john@remedajs.com" },
    { name: "jane", email: "jane@remedajs.com" },
  ],
  R.pullObject(R.prop("email"), R.prop("name")),
); // => { john: "john@remedajs.com", jane: "jane@remedajs.com" }

Sets the value at prop of object.

Data First

R.set(obj, prop, value);
R.set({ a: 1 }, "a", 2); // => { a: 2 }

Data Last

R.set(prop, value)(obj);
R.pipe({ a: 1 }, R.set("a", 2)); // => { a: 2 }

Sets the value at path of object.

Data First

R.setPath(obj, path, value);
R.setPath({ a: { b: 1 } }, ["a", "b"], 2); // => { a: { b: 2 } }

Data Last

R.setPath(path, value)(obj);
R.pipe({ a: { b: 1 } }, R.setPath(["a", "b"], 2)); // { a: { b: 2 } }

swapProps

Object
View source on GitHub

Swaps the positions of two properties in an object based on the provided keys.

Data First

swap(data, key1, key2);
swap({ a: 1, b: 2, c: 3 }, "a", "b"); // => {a: 2, b: 1, c: 3}

Data Last

swap(key1, key2)(data);
swap("a", "b")({ a: 1, b: 2, c: 3 }); // => {a: 2, b: 1, c: 3}

uniqueWith

Object
View source on GitHub

Returns a new array containing only one copy of each element in the original list. Elements are compared by custom comparator isEquals.

Data First

R.uniqueWith(array, isEquals);
R.uniqueWith(
  [{ a: 1 }, { a: 2 }, { a: 2 }, { a: 5 }, { a: 1 }, { a: 6 }, { a: 7 }],
  R.equals,
); // => [{a: 1}, {a: 2}, {a: 5}, {a: 6}, {a: 7}]

Data Last

R.uniqueWith(isEquals)(array);
R.uniqueWith(R.equals)([
  { a: 1 },
  { a: 2 },
  { a: 2 },
  { a: 5 },
  { a: 1 },
  { a: 6 },
  { a: 7 },
]); // => [{a: 1}, {a: 2}, {a: 5}, {a: 6}, {a: 7}]
R.pipe(
  [{ a: 1 }, { a: 2 }, { a: 2 }, { a: 5 }, { a: 1 }, { a: 6 }, { a: 7 }], // only 4 iterations
  R.uniqueWith(R.equals),
  R.take(3),
); // => [{a: 1}, {a: 2}, {a: 5}]

values

Object
pipeable
View source on GitHub

Returns a new array containing the values of the array or object.

Data First

R.values(source);
R.values(["x", "y", "z"]); // => ['x', 'y', 'z']
R.values({ a: "x", b: "y", c: "z" }); // => ['x', 'y', 'z']
R.pipe(["x", "y", "z"], R.values); // => ['x', 'y', 'z']
R.pipe({ a: "x", b: "y", c: "z" }, R.values); // => ['x', 'y', 'z']
R.pipe({ a: "x", b: "y", c: "z" }, R.values, R.first); // => 'x'

Determines whether all predicates returns true for the input data.

Data First

R.allPass(data, fns);
const isDivisibleBy3 = (x: number) => x % 3 === 0;
const isDivisibleBy4 = (x: number) => x % 4 === 0;
const fns = [isDivisibleBy3, isDivisibleBy4];
R.allPass(12, fns); // => true
R.allPass(8, fns); // => false

Data Last

R.allPass(fns)(data);
const isDivisibleBy3 = (x: number) => x % 3 === 0;
const isDivisibleBy4 = (x: number) => x % 4 === 0;
const fns = [isDivisibleBy3, isDivisibleBy4];
R.allPass(fns)(12); // => true
R.allPass(fns)(8); // => false

Determines whether any predicate returns true for the input data.

Data First

R.anyPass(data, fns);
const isDivisibleBy3 = (x: number) => x % 3 === 0;
const isDivisibleBy4 = (x: number) => x % 4 === 0;
const fns = [isDivisibleBy3, isDivisibleBy4];
R.anyPass(8, fns); // => true
R.anyPass(11, fns); // => false

Data Last

R.anyPass(fns)(data);
const isDivisibleBy3 = (x: number) => x % 3 === 0;
const isDivisibleBy4 = (x: number) => x % 4 === 0;
const fns = [isDivisibleBy3, isDivisibleBy4];
R.anyPass(fns)(8); // => true
R.anyPass(fns)(11); // => false

Split an array into groups the length of size. If array can't be split evenly, the final chunk will be the remaining elements.

Data First

R.chunk(array, size);
R.chunk(["a", "b", "c", "d"], 2); // => [['a', 'b'], ['c', 'd']]
R.chunk(["a", "b", "c", "d"], 3); // => [['a', 'b', 'c'], ['d']]

Data Last

R.chunk(size)(array);
R.chunk(2)(["a", "b", "c", "d"]); // => [['a', 'b'], ['c', 'd']]
R.chunk(3)(["a", "b", "c", "d"]); // => [['a', 'b', 'c'], ['d']]

Combines two arrays.

Data First

R.concat(arr1, arr2);
R.concat([1, 2, 3], ["a"]); // [1, 2, 3, 'a']

Data Last

R.concat(arr2)(arr1);
R.concat(["a"])([1, 2, 3]); // [1, 2, 3, 'a']

differenceWith

Array
pipeable
View source on GitHub

Excludes the values from other array. Elements are compared by custom comparator isEquals.

Data First

R.differenceWith(array, other, isEquals);
R.differenceWith(
  [{ a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }],
  [{ a: 2 }, { a: 5 }, { a: 3 }],
  R.equals,
); // => [{a: 1}, {a: 4}]

Data Last

R.differenceWith(other, isEquals)(array);
R.differenceWith(
  [{ a: 2 }, { a: 5 }, { a: 3 }],
  R.equals,
)([{ a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }]); // => [{a: 1}, {a: 4}]
R.pipe(
  [{ a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }, { a: 5 }, { a: 6 }], // only 4 iterations
  R.differenceWith([{ a: 2 }, { a: 3 }], R.equals),
  R.take(2),
); // => [{a: 1}, {a: 4}]

drop

Array
pipeable
View source on GitHub

Removes first n elements from the array.

Data First

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

Data Last

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

dropFirstBy

Array
View source on GitHub

Drop the first n items from data based on the provided ordering criteria. This allows you to avoid sorting the array before dropping the items. The complexity of this function is O(Nlogn) where N is the length of the array.

For the opposite operation (to keep n elements) see takeFirstBy.

Data First

R.dropFirstBy(data, n, ...rules);
R.dropFirstBy(["aa", "aaaa", "a", "aaa"], 2, (x) => x.length); // => ['aaa', 'aaaa']

Data Last

R.dropFirstBy(n, ...rules)(data);
R.pipe(
  ["aa", "aaaa", "a", "aaa"],
  R.dropFirstBy(2, (x) => x.length),
); // => ['aaa', 'aaaa']

Removes last n elements from the array.

Data First

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

Data Last

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

dropLastWhile

Array
View source on GitHub

Removes elements from the end of the array until the predicate returns false.

The predicate is applied to each element in the array starting from the end and moving towards the beginning, until the predicate returns false. The returned array includes elements from the beginning of the array, up to and including the element that produced false for the predicate.

Data First

R.dropLastWhile(data, predicate);
R.dropLastWhile([1, 2, 10, 3, 4], (x) => x < 10); // => [1, 2, 10]

Data Last

R.dropLastWhile(predicate)(data);
R.pipe(
  [1, 2, 10, 3, 4],
  R.dropLastWhile((x) => x < 10),
); // => [1, 2, 10]

dropWhile

Array
View source on GitHub

Removes elements from the beginning of the array until the predicate returns false.

The predicate is applied to each element in the array, until the predicate returns false. The returned array includes the rest of the elements, starting with the element that produced false for the predicate.

Data First

R.dropWhile(data, predicate);
R.dropWhile([1, 2, 10, 3, 4], (x) => x < 10); // => [10, 3, 4]

Data Last

R.dropWhile(predicate)(data);
R.pipe(
  [1, 2, 10, 3, 4],
  R.dropWhile((x) => x < 10),
); // => [10, 3, 4]

filter

Array
pipeable
indexed
View source on GitHub

Filter the elements of an array that meet the condition specified in a callback function.

Data First

R.filter(array, fn);
R.filter.indexed(array, fn);
R.filter([1, 2, 3], (x) => x % 2 === 1); // => [1, 3]
R.filter.indexed([1, 2, 3], (x, i, array) => x % 2 === 1); // => [1, 3]

Data Last

R.filter(fn)(array);
R.filter.indexed(fn)(array);
R.pipe(
  [1, 2, 3],
  R.filter((x) => x % 2 === 1),
); // => [1, 3]
R.pipe(
  [1, 2, 3],
  R.filter.indexed((x, i) => x % 2 === 1),
); // => [1, 3]

find

Array
pipeable
indexed
View source on GitHub

Returns the value of the first element in the array where predicate is true, and undefined otherwise.

Data First

R.find(items, fn);
R.find.indexed(items, fn);
R.find([1, 3, 4, 6], (n) => n % 2 === 0); // => 4
R.find.indexed([1, 3, 4, 6], (n, i) => n % 2 === 0); // => 4

Data Last

R.find(fn)(items);
R.find.indexed(fn)(items);
R.pipe(
  [1, 3, 4, 6],
  R.find((n) => n % 2 === 0),
); // => 4
R.pipe(
  [1, 3, 4, 6],
  R.find.indexed((n, i) => n % 2 === 0),
); // => 4

findIndex

Array
pipeable
indexed
View source on GitHub

Returns the index of the first element in the array where predicate is true, and -1 otherwise.

Data First

R.findIndex(items, fn);
R.findIndex.indexed(items, fn);
R.findIndex([1, 3, 4, 6], (n) => n % 2 === 0); // => 2
R.findIndex.indexed([1, 3, 4, 6], (n, i) => n % 2 === 0); // => 2

Data Last

R.findIndex(fn)(items);
R.findIndex.indexed(fn)(items);
R.pipe(
  [1, 3, 4, 6],
  R.findIndex((n) => n % 2 === 0),
); // => 2
R.pipe(
  [1, 3, 4, 6],
  R.findIndex.indexed((n, i) => n % 2 === 0),
); // => 2

findLast

Array
pipeable
indexed
View source on GitHub

Returns the value of the last element in the array where predicate is true, and undefined otherwise.

Data First

R.findLast(items, fn);
R.findLast.indexed(items, fn);
R.findLast([1, 3, 4, 6], (n) => n % 2 === 1); // => 3
R.findLast.indexed([1, 3, 4, 6], (n, i) => n % 2 === 1); // => 3

Data Last

R.findLast(fn)(items);
R.findLast.indexed(fn)(items);
R.pipe(
  [1, 3, 4, 6],
  R.findLast((n) => n % 2 === 1),
); // => 3
R.pipe(
  [1, 3, 4, 6],
  R.findLast.indexed((n, i) => n % 2 === 1),
); // => 3

findLastIndex

Array
pipeable
indexed
View source on GitHub

Returns the index of the last element in the array where predicate is true, and -1 otherwise.

Data First

R.findLastIndex(items, fn);
R.findLastIndex.indexed(items, fn);
R.findLastIndex([1, 3, 4, 6], (n) => n % 2 === 1); // => 1
R.findLastIndex.indexed([1, 3, 4, 6], (n, i) => n % 2 === 1); // => 1

Data Last

R.findLastIndex(fn)(items);
R.findLastIndex.indexed(fn)(items);
R.pipe(
  [1, 3, 4, 6],
  R.findLastIndex((n) => n % 2 === 1),
); // => 1
R.pipe(
  [1, 3, 4, 6],
  R.findLastIndex.indexed((n, i) => n % 2 === 1),
); // => 1

first

Array
pipeable
View source on GitHub

Gets the first element of array.

Data First

R.first(array);
R.first([1, 2, 3]); // => 1
R.first([]); // => undefined

Data Last

R.first()(array);
R.pipe(
  [1, 2, 4, 8, 16],
  R.filter((x) => x > 3),
  R.first(),
  (x) => x + 1,
); // => 5

Find the first element in the array that adheres to the order rules provided. This is a superset of what a typical maxBy or minBy function would do as it allows defining "tie-breaker" rules when values are equal, and allows comparing items using any logic. This function is equivalent to calling R.first(R.sortBy(...)) but runs at O(n) instead of O(nlogn).

Use nthBy if you need an element other that the first, or takeFirstBy if you more than just the first element.

Data Last

R.firstBy(...rules)(data);
const max = R.pipe([1, 2, 3], R.firstBy([R.identity, "desc"])); // => 3;
const min = R.pipe([1, 2, 3], R.firstBy(R.identity)); // => 1;

const data = [{ a: "a" }, { a: "aa" }, { a: "aaa" }] as const;
const maxBy = R.pipe(data, R.firstBy([(item) => item.a.length, "desc"])); // => { a: "aaa" };
const minBy = R.pipe(
  data,
  R.firstBy((item) => item.a.length),
); // => { a: "a" };

const data = [
  { type: "cat", size: 1 },
  { type: "cat", size: 2 },
  { type: "dog", size: 3 },
] as const;
const multi = R.pipe(data, R.firstBy(R.prop("type"), [R.prop("size"), "desc"])); // => {type: "cat", size: 2}

Data First

R.firstBy(data, ...rules);
const max = R.firstBy([1, 2, 3], [R.identity, "desc"]); // => 3;
const min = R.firstBy([1, 2, 3], R.identity); // => 1;

const data = [{ a: "a" }, { a: "aa" }, { a: "aaa" }] as const;
const maxBy = R.firstBy(data, [(item) => item.a.length, "desc"]); // => { a: "aaa" };
const minBy = R.firstBy(data, (item) => item.a.length); // => { a: "a" };

const data = [
  { type: "cat", size: 1 },
  { type: "cat", size: 2 },
  { type: "dog", size: 3 },
] as const;
const multi = R.firstBy(data, R.prop("type"), [R.prop("size"), "desc"]); // => {type: "cat", size: 2}

flat

Array
pipeable
View source on GitHub

Creates a new array with all sub-array elements concatenated into it recursively up to the specified depth. Equivalent to the built-in Array.prototype.flat method.

Data First

R.flat(data);
R.flat(data, depth);
R.flat([[1, 2], [3, 4], [5], [[6]]]); // => [1, 2, 3, 4, 5, [6]]
R.flat([[[1]], [[2]]], 2); // => [1, 2]

Data Last

R.flat()(data);
R.flat(depth)(data);
R.pipe([[1, 2], [3, 4], [5], [[6]]], R.flat()); // => [1, 2, 3, 4, 5, [6]]
R.pipe([[[1]], [[2]]], R.flat(2)); // => [1, 2]

flatMap

Array
pipeable
View source on GitHub

Map each element of an array using a defined callback function and flatten the mapped result.

Data First

R.flatMap(array, fn);
R.flatMap([1, 2, 3], (x) => [x, x * 10]); // => [1, 10, 2, 20, 3, 30]

Data Last

R.flatMap(fn)(array);
R.pipe(
  [1, 2, 3],
  R.flatMap((x) => [x, x * 10]),
); // => [1, 10, 2, 20, 3, 30]

forEach

Array
pipeable
indexed
View source on GitHub

Iterate an array using a defined callback function. The original array is returned instead of void.

Data First

R.forEach(array, fn);
R.forEach.indexed(array, fn);
R.forEach([1, 2, 3], (x) => {
  console.log(x);
}); // => [1, 2, 3]
R.forEach.indexed([1, 2, 3], (x, i) => {
  console.log(x, i);
}); // => [1, 2, 3]

Data Last

R.forEach(fn)(array);
R.forEach.indexed(fn)(array);
R.pipe(
  [1, 2, 3],
  R.forEach((x) => {
    console.log(x);
  }),
); // => [1, 2, 3]
R.pipe(
  [1, 2, 3],
  R.forEach.indexed((x, i) => {
    console.log(x, i);
  }),
); // => [1, 2, 3]

groupBy

Array
indexed
strict
View source on GitHub

Splits a collection into sets, grouped by the result of running each value through fn.

Data First

R.groupBy(array, fn);
R.groupBy.strict(array, fn);
R.groupBy(["one", "two", "three"], (x) => x.length); // => {3: ['one', 'two'], 5: ['three']}
R.groupBy.strict([{ a: "cat" }, { a: "dog" }] as const, prop("a")); // => {cat: [{a: 'cat'}], dog: [{a: 'dog'}]} typed Partial<Record<'cat' | 'dog', NonEmptyArray<{a: 'cat' | 'dog'}>>>
R.groupBy([0, 1], (x) => (x % 2 === 0 ? "even" : undefined)); // => {even: [0]}

Data Last

R.groupBy(fn)(array);
R.pipe(
  ["one", "two", "three"],
  R.groupBy((x) => x.length),
); // => {3: ['one', 'two'], 5: ['three']}

hasAtLeast

Array
View source on GitHub

Checks if the given array has at least the defined number of elements. When the minimum used is a literal (e.g. 3) the output is refined accordingly so that those indices are defined when accessing the array even when using typescript's 'noUncheckedIndexAccess'.

Data First

R.hasAtLeast(data, minimum);
R.hasAtLeast([], 4); // => false

const data: number[] = [1, 2, 3, 4];
R.hasAtLeast(data, 1); // => true
data[0]; // 1, with type `number`

Data Last

R.hasAtLeast(minimum)(data);
R.pipe([], R.hasAtLeast(4)); // => false

const data = [[1, 2], [3], [4, 5]];
R.pipe(
  data,
  R.filter(R.hasAtLeast(2)),
  R.map(([, second]) => second),
); // => [2,5], with type `number[]`

indexBy

Array
indexed
strict
View source on GitHub

Converts a list of objects into an object indexing the objects by the given key (casted to a string). Use the strict version to maintain the given key's type, so long as it is a valid PropertyKey.

There are several other functions that could be used to build an object from an array:

  • fromKeys - Builds an object from an array of keys and a mapper for values.
  • pullObject - Builds an object from an array of items with mappers for both keys and values.
  • fromEntries - Builds an object from an array of key-value pairs.
  • mapToObj - Builds an object from an array of items and a single mapper for key-value pairs. Refer to the docs for more details.

Data First

R.indexBy(array, fn);
R.indexBy.strict(array, fn);
R.indexBy(["one", "two", "three"], (x) => x.length); // => {"3": 'two', "5": 'three'}
R.indexBy.strict(["one", "two", "three"], (x) => x.length); // => {3: 'two', 5: 'three'}

Data Last

R.indexBy(fn)(array);
R.indexBy.strict(fn)(array);
R.pipe(
  ["one", "two", "three"],
  R.indexBy((x) => x.length),
); // => {"3": 'two', "5": 'three'}
R.pipe(
  ["one", "two", "three"],
  R.indexBy.strict((x) => x.length),
); // => {3: 'two', 5: 'three'}

intersectionWith

Array
pipeable
View source on GitHub

Returns a list of intersecting values based on a custom comparator function that compares elements of both arrays.

Data First

R.intersectionWith(array, other, comparator);
R.intersectionWith(
  [
    { id: 1, name: "Ryan" },
    { id: 3, name: "Emma" },
  ],
  [3, 5],
  (a, b) => a.id === b,
); // => [{ id: 3, name: 'Emma' }]

Data Last

R.intersectionWith(other, comparator)(array);
R.intersectionWith(
  [3, 5],
  (a, b) => a.id === b,
)([
  { id: 1, name: "Ryan" },
  { id: 3, name: "Emma" },
]); // => [{ id: 3, name: 'Emma' }]

Joins the elements of the array by: casting them to a string and concatenating them one to the other, with the provided glue string in between every two elements.

When called on a tuple and with stricter item types (union of literal values, the result is strictly typed to the tuples shape and it's item types).

Data First

R.join(data, glue);
R.join([1, 2, 3], ","); // => "1,2,3" (typed `string`)
R.join(["a", "b", "c"], ""); // => "abc" (typed `string`)
R.join(["hello", "world"] as const, " "); // => "hello world" (typed `hello world`)

Data Last

R.join(glue)(data);
R.pipe([1, 2, 3], R.join(",")); // => "1,2,3" (typed `string`)
R.pipe(["a", "b", "c"], R.join("")); // => "abc" (typed `string`)
R.pipe(["hello", "world"] as const, R.join(" ")); // => "hello world" (typed `hello world`)

last

Array
pipeable
View source on GitHub

Gets the last element of array.

Data First

R.last(array);
R.last([1, 2, 3]); // => 3
R.last([]); // => undefined

Data Last

R.last()(array);
R.pipe(
  [1, 2, 4, 8, 16],
  R.filter((x) => x > 3),
  R.last(),
  (x) => x + 1,
); // => 17

Counts values of the collection or iterable.

Data First

R.length(array);
R.length([1, 2, 3]); // => 3

Data Last

R.length()(array);
R.pipe([1, 2, 3], R.length()); // => 3

map

Array
pipeable
indexed
strict
View source on GitHub

Map each element of an array using a defined callback function. If the input array is a tuple use the strict variant to maintain it's shape.

Data First

R.map(array, fn);
R.map.indexed(array, fn);
R.map.strict(array, fn);
R.map.strict.indexed(array, fn);
R.map([1, 2, 3], (x) => x * 2); // => [2, 4, 6], typed number[]
R.map.indexed([0, 0, 0], (x, i) => i); // => [0, 1, 2], typed number[]
R.map.strict([0, 0] as const, (x) => x + 1); // => [1, 1], typed [number, number]
R.map.strict.indexed([0, 0] as const, (x, i) => x + i); // => [0, 1], typed [number, number]

Data Last

R.map(fn)(array);
R.map.indexed(fn)(array);
R.pipe(
  [0, 1, 2],
  R.map((x) => x * 2),
); // => [0, 2, 4]
R.pipe(
  [0, 0, 0],
  R.map.indexed((x, i) => i),
); // => [0, 1, 2]

mapToObj

Array
indexed
View source on GitHub

Map each element of an array into an object using a defined callback function.

There are several other functions that could be used to build an object from an array:

  • fromKeys - Builds an object from an array of keys and a mapper for values.
  • indexBy - Builds an object from an array of values and a mapper for keys.
  • pullObject - Builds an object from an array of items with mappers for both keys and values.
  • fromEntries - Builds an object from an array of key-value pairs. Refer to the docs for more details.

Data First

R.mapToObj(array, fn);
R.mapToObj.indexed(array, fn);
R.mapToObj([1, 2, 3], (x) => [String(x), x * 2]); // => {1: 2, 2: 4, 3: 6}
R.mapToObj.indexed([0, 0, 0], (x, i) => [i, i]); // => {0: 0, 1: 1, 2: 2}

Data Last

R.mapToObj(fn)(array);
R.mapToObj.indexed(fn)(array);
R.pipe(
  [1, 2, 3],
  R.mapToObj((x) => [String(x), x * 2]),
); // => {1: 2, 2: 4, 3: 6}
R.pipe(
  [0, 0, 0],
  R.mapToObj.indexed((x, i) => [i, i]),
); // => {0: 0, 1: 1, 2: 2}

mapWithFeedback

Array
pipeable
indexed
View source on GitHub

Applies a function on each element of the array, using the result of the previous application, and returns an array of the successively computed values.

Data First

R.mapWithFeedback(items, fn, initialValue);
R.mapWithFeedback.indexed(items, fn, initialValue);
R.mapWithFeedback([1, 2, 3, 4, 5], (prev, x) => prev + x, 100); // => [101, 103, 106, 110, 115]
R.mapWithFeedback.indexed(
  [1, 2, 3, 4, 5],
  (prev, x, i, array) => prev + x,
  100,
); // => [101, 103, 106, 110, 115]

Data Last

R.mapWithFeedback(fn, initialValue)(array);
R.pipe(
  [1, 2, 3, 4, 5],
  R.mapWithFeedback((prev, x) => prev + x, 100),
); // => [101, 103, 106, 110, 115]
R.pipe(
  [1, 2, 3, 4, 5],
  R.mapWithFeedback.indexed((prev, x, i, array) => prev + x, 100),
); // => [101, 103, 106, 110, 115]

meanBy

Array
indexed
View source on GitHub

Returns the mean of the elements of an array using the provided predicate.

Data Last

R.meanBy(fn)(array);
R.meanBy.indexed(fn)(array);
R.pipe(
  [{ a: 5 }, { a: 1 }, { a: 3 }],
  R.meanBy((x) => x.a),
); // 3

Data First

R.meanBy(array, fn);
R.meanBy.indexed(array, fn);
R.meanBy([{ a: 5 }, { a: 1 }, { a: 3 }], (x) => x.a); // 3

Merges a list of objects into a single object.

R.mergeAll(objects);
R.mergeAll([{ a: 1, b: 1 }, { b: 2, c: 3 }, { d: 10 }]); // => { a: 1, b: 2, c: 3, d: 10 }

Retrieves the element that would be at the given index if the array were sorted according to specified rules. This function uses the QuickSelect algorithm running at an average complexity of O(n). Semantically it is equivalent to sortBy(data, ...rules).at(index) which would run at O(nlogn).

See also firstBy which provides an even more efficient algorithm and a stricter return type, but only for index === 0. See takeFirstBy to get all the elements up to and including index.

Data First

R.nthBy(data, index, ...rules);
R.nthBy([2, 1, 4, 5, 3], 2, identity); // => 3

Data Last

R.nthBy(index, ...rules)(data);
R.pipe([2, 1, 4, 5, 3], R.nthBy(2, identity)); // => 3

only

Array
pipeable
View source on GitHub

Returns the first and only element of array, or undefined otherwise.

Data First

R.only(array);
R.only([]); // => undefined
R.only([1]); // => 1
R.only([1, 2]); // => undefined

Data Last

R.only()(array);
R.pipe([], R.only()); // => undefined
R.pipe([1], R.only()); // => 1
R.pipe([1, 2], R.only()); // => undefined

partition

Array
indexed
View source on GitHub

Splits a collection into two groups, the first of which contains elements the predicate type guard passes, and the second one containing the rest.

Data First

R.partition(array, fn);
R.partition(["one", "two", "forty two"], (x) => x.length === 3); // => [['one', 'two'], ['forty two']]

Data First

R.partition(array, fn);
R.partition(["one", "two", "forty two"], (x) => x.length === 3); // => [['one', 'two'], ['forty two']]

Data Last

R.partition(fn)(array);
R.pipe(
  ["one", "two", "forty two"],
  R.partition((x) => x.length === 3),
); // => [['one', 'two'], ['forty two']]

Data Last

R.partition(fn)(array);
R.pipe(
  ["one", "two", "forty two"],
  R.partition((x) => x.length === 3),
); // => [['one', 'two'], ['forty two']]

Returns a list of numbers from start (inclusive) to end (exclusive).

Data First

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

Data First

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

Calculates the rank of an item in an array based on rules. The rank is the position where the item would appear in the sorted array. This function provides an efficient way to determine the rank in O(n) time, compared to O(nlogn) for the equivalent sortedIndex(sortBy(data, ...rules), item).

Data First

R.rankBy(data, item, ...rules);
const DATA = [{ a: 5 }, { a: 1 }, { a: 3 }] as const;
R.rankBy(DATA, 0, R.prop("a")); // => 0
R.rankBy(DATA, 1, R.prop("a")); // => 1
R.rankBy(DATA, 2, R.prop("a")); // => 1
R.rankBy(DATA, 3, R.prop("a")); // => 2

Data Last

R.rankBy(item, ...rules)(data);
const DATA = [{ a: 5 }, { a: 1 }, { a: 3 }] as const;
R.pipe(DATA, R.rankBy(0, R.prop("a"))); // => 0
R.pipe(DATA, R.rankBy(1, R.prop("a"))); // => 1
R.pipe(DATA, R.rankBy(2, R.prop("a"))); // => 1
R.pipe(DATA, R.rankBy(3, R.prop("a"))); // => 2

reduce

Array
indexed
View source on GitHub

Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.

Data First

R.reduce(items, fn, initialValue);
R.reduce.indexed(items, fn, initialValue);
R.reduce([1, 2, 3, 4, 5], (acc, x) => acc + x, 100); // => 115
R.reduce.indexed([1, 2, 3, 4, 5], (acc, x, i, array) => acc + x, 100); // => 115

Data Last

R.reduce(fn, initialValue)(array);
R.pipe(
  [1, 2, 3, 4, 5],
  R.reduce((acc, x) => acc + x, 100),
); // => 115
R.pipe(
  [1, 2, 3, 4, 5],
  R.reduce.indexed((acc, x, i, array) => acc + x, 100),
); // => 115

Reverses array.

Data First

R.reverse(arr);
R.reverse([1, 2, 3]); // [3, 2, 1]

Data Last

R.reverse()(array);
R.reverse()([1, 2, 3]); // [3, 2, 1]

sample

Array
pipeable
View source on GitHub

Returns a random subset of size sampleSize from array.

Maintains and infers most of the typing information that could be passed along to the output. This means that when using tuples, the output will be a tuple too, and when using literals, those literals would be preserved.

The items in the result are kept in the same order as they are in the input. If you need to get a shuffled response you can pipe the shuffle function after this one.

Data First

R.sample(array, sampleSize);
R.sample(["hello", "world"], 1); // => ["hello"] // typed string[]
R.sample(["hello", "world"] as const, 1); // => ["world"] // typed ["hello" | "world"]

Data Last