Migrate: ramda

addIndex

View source on GitHub

Not provided by Remeda.

You don’t need addIndex In Remeda because all functions that iterate over arrays or objects have their callbacks in the format that addIndex returns by default. If you still have a use-case that isn’t possible via Remeda please open an issue at the Remeda GitHub project.

// Ramda
addIndex(map)((val, idx) => idx + "-" + val, DATA);

// Remeda
map(DATA, (val, idx) => idx + "-" + val);
constant

Use constant with the constant false. Notice that in Ramda you use F itself as the function, but in Remeda constant is a factory that creates the replacement function.

// Ramda
F;

// Remeda
constant(false);

identity

View source on GitHub
identity

In Remeda the identity function is a factory that creates an identity function; it needs to be called to be used.

// Ramda
map(identity);

// Remeda
map(identity());

partial

View source on GitHub
partialBind

Remeda’s partialBind takes a variadic list of arguments instead of an array.

function greet(greeting, firstName, lastName) {
  return greeting + " " + firstName + " " + lastName;
}

// Ramda
partial(greet, ["hi", "john"]);

// Remeda
partialBind(greet, "hi", "john");

partialRight

View source on GitHub
partialLastBind

Remeda’s partialLastBind takes a variadic list of arguments instead of an array.

function greet(greeting, firstName, lastName) {
  return greeting + " " + firstName + " " + lastName;
}

// Ramda
partialRight(greet, ["john", "doe"]);

// Remeda
partialLastBind(greet, "john", "doe");
constant

Use constant with the constant true. Notice that in Ramda you use T itself as the function, but in Remeda constant is a factory that creates the replacement function.

// Ramda
T;

// Remeda
constant(true);
concat

Not provided by Remeda.

  • You can replicate this function via the native JS spread ... operator or via the Remeda concat function (by wrapping the operand with an array).
  • There might be cases where building an append function could be more efficient than using the suggested alternatives, but we believe they are extremely rare. If you want to suggest adding it reach out to us at the Remeda GitHub project.
// Ramda
append(operand, DATA);

// Or curried
const addsAbc = append(operand);

// Remeda
concat(DATA, [operand]);

// Or in a pipe
pipe(DATA, concat([operand]));

// Native
[...DATA, operand];

const addsAbc = <T extends ReadonlyArray<unknown>>(data: T) => [
  ...data,
  operand,
];
flat

Unlike flatten in Ramda, the Remeda flat function is always bound by the depth param. To replicate the Ramda behavior use a high, const value. Infinity and Number.MAX_INTEGER are not consts and would result in inefficient typing.

// Ramda
flatten(DATA);

// Remeda
flat(DATA, 100); // ✅
flat(DATA, Infinity); // ❌
isIncludedIn

Arrays

// Ramda
includes(1, [1, 2, 3]);

// Remeda
isIncludedIn(1, [1, 2, 3]);

Strings

const DATA = "Hello, World!";

// Remeda
includes("lo", DATA);

// Native
DATA.includes("lo");

Object items

const DATA = [{ name: "Fred" }];

// Ramda
includes({ name: "Fred" }, DATA);

// Remeda
DATA.some(isDeepEqual({ name: "Fred" }));

Array items

const DATA = [[42]];

// Ramda
includes([42], DATA);

// Remeda
DATA.some(isDeepEqual([42]));
dropLast
  • Equivalent to dropLast with an argument of 1.
  • On strings use sliceString with 0 and -1 as arguments instead.

Arrays

// Ramda
init([1, 2, 3]);

// Remeda
dropLast([1, 2, 3], 1);

Strings

// Ramda
init("abc");

// Remeda
sliceString("abc", 0, -1);
last

For strings use sliceString with -1 as an argument instead.

Arrays

// Ramda
last([1, 2, 3]);

// Remeda
last([1, 2, 3]);

Strings

// Ramda
last("abc");

// Remeda
sliceString("abc", -1);
mapWithFeedback

Remeda’s mapWithFeedback has some differences from Ramda’s mapAccum, but could be used to achieve the same results:

  • The mapper function only returns a single value for both the accumulator and the value (like reduce does). mapWithFeedback would not work if you need these to have different values.
  • Only the accumulated array is returned instead of a tuple. The final result of the computation would always be the last element in this list, and could be retrieved using last.
// Ramda
const result = mapAccum((a, b) => [a + b, a + b], 0, ["1", "2", "3", "4"]);

// Remeda
const temp = mapWithFeedback(["1", "2", "3", "4"], (a, b) => a + b, 0);
const result = [last(temp), temp];

Not provided by Remeda.

  • For index 0 use first.
  • For index -1 use last.
  • For arbitrary non-negative indices use the native JS data[n].
  • Or use Array.prototype.at for any index.
// Ramda
nth(0, DATA);

// Remeda
first(DATA);

// Ramda
nth(1, DATA);

// Native
DATA[1];
DATA.at(1);

// Ramda
nth(-1, DATA);

// Remeda
last(DATA);

// Ramda
nth(-2, DATA);

// Native
DATA.at(-2);
map

Not provided by Remeda.

  • pluck(data, k) is equivalent to map(data, prop(k)).

  • When data is an object (and not an array) use mapValues instead.

Arrays

const DATA = [{ val: "hello" }, { val: "world" }];

// Ramda
R.pluck("val", DATA); //=> ["hello", "world"];

// Remeda
map(DATA, prop("val"));

Objects

const DATA = { a: { val: "hello" }, b: { val: "world" } };

// Ramda
R.pluck("val", DATA); //=> { a: "hello", b: "world" };

// Remeda
mapValues(DATA, prop("val"));
filter

Wrap the callback with isNot.

// Ramda
reject(predicate, DATA);

// Remeda
filter(DATA, isNot(predicate));

// Or in a pipe
pipe(DATA, filter(isNot(predicate)));
drop
  • Equivalent to drop with an argument of 1.
  • On strings use sliceString instead.

Arrays

// Ramda
tail([1, 2, 3]);

// Remeda
drop([1, 2, 3], 1);

Strings

// Ramda
tail("abc");

// Remeda
sliceString("abc", 1);

Not provided by Remeda.

Compose zip and fromEntries:

// Ramda
zipObj(keys, values);

// Remeda
fromEntries(zip(keys, values));
when
  • Use Remeda’s [when] with isNullish as the predicate and the fallback value wrapped with constant.
  • For defaulting NaN values use the built-in Number.isNaN instead.
  • For both you’d need to construct a type-guard manually.

Nullish

// Ramda
defaultTo(DATA, 10);

// Remeda
when(DATA, isNullish, constant(10));

NaN

// Ramda
defaultTo(DATA, 10);

// Remeda
when(DATA, Number.isNaN, constant(10));

Both

// Ramda
defaultTo(DATA, 10);

// Remeda
when(
  DATA,
  (x) => x === undefined || x === null || Number.isNaN(x),
  constant(10),
);
when
  • Remeda supports both if-like statements, and if-else-like statements (which is what Ramda’s ifElse function supports); The former is done by using a predicate function and a mapper function, and the latter is done by wrapping both mappers with an object.
  • To support extra arguments Ramda requires one of the functions provided to provide full typing to all params, in Remeda this isn’t needed as the extra arguments would be inferred from the call site.

if-else

// Ramda
ifElse(predicate, onTrue, onFalse)(data);

// Remeda
when(data, predicate, { onTrue, onFalse });

// Or in a pipe
pipe(data, when(predicate, { onTrue, onFalse }));

if

ifElse(predicate, onTrue, identity)(data);

// Remeda
when(data, predicate, onTrue);

// Or in a pipe
pipe(data, when(predicate, onTrue));

extra args

// Ramda
const mapper = ifElse(
  (x: string | undefined, index: number) => x === undefined,
  (_, index) => `item_${index}`,
  identity,
);
map(data, mapper);

// Remeda
map(
  data,
  when(
    (x) => x === undefined,
    (_, index) => `item_${index}`,
  ),
);
isNot

The function only accepts boolean values, to support arbitrary values compose it with isTruthy.

Booleans

// Ramda
not(val);

// Remeda
isNot(val);

Arbitrary

// Ramda
not(val);

// Remeda
isNot(isTruthy(val));
subtract

Use subtract with an operand of 1.

// Ramda
dec(value);

// Remeda
subtract(value, 1);
add

Use add with an operand of 1.

// Ramda
inc(value);

// Remeda
add(value, 1);
multiply

Use multiply with an operand of -1.

// Ramda
negate(value);

// Remeda
multiply(value, -1);

Not provided by Remeda.

The Ramda max function takes exactly 2 arguments. It is easily replicated using native JS operators.

// Ramda
max(a, b);

// Curried
const maxA = max(a);

// Native
a > b ? a : b;

const maxA = (b: number) => (a > b ? a : b);
firstBy

The Remeda firstBy returns what would be the first item in an array if it was sorted by the order criteria (without actually sorting the array). Ramda’s maxBy could be rebuilt using firstBy by taking the mapping function in descending order, and wrapping the 2 arguments with an array.

// Ramda
maxBy(mapperFunc, a, b);

// Remeda
firstBy([a, b], [mapperFunc, "desc"]);

Not provided by Remeda.

The Ramda max function takes exactly 2 arguments. It is easily replicated using native JS operators.

// Ramda
min(a, b);

// Curried
const minA = min(a);

// Native
a < b ? a : b;

const minA = (b: number) => (a < b ? a : b);
firstBy

The Remeda firstBy returns what would be the first item in an array if it was sorted by the order criteria (without actually sorting the array). Ramda’s minBy could be rebuilt using firstBy by taking the mapping function in, and wrapping the 2 arguments with an array.

// Ramda
minBy(mapperFunc, a, b);

// Remeda
firstBy([a, b], mapperFunc);

sortWith

View source on GitHub
sortBy

Remeda’s sortBy also covers the use-case of sortWith using a simpler syntax to describe complex sorting logic; the function takes a variadic list of arguments instead of an array, and the sorting direction (ascending/descending) is determined by an optional tuple syntax for the operator.

const DATA = [
  {
    name: "clara",
    age: 40,
  },
  {
    name: "bob",
    age: 30,
  },
  {
    name: "alice",
    age: 40,
  },
];

// Ramda
sortWith([descend(prop("age")), ascend(prop("name"))])(DATA);

// Remeda
sortBy(DATA, [prop("age"), "desc"], prop("name"));

// Or in a pipe
pipe(DATA, sortBy([prop("age"), "desc"], prop("name")));