---
title: "Coming from Ramda"
description: "Map Ramda functions to @vinicunca/perkakas, with notes where the APIs differ."
canonical_url: "https://vinicunca.dev/perkakas/migrate/ramda"
---
# Coming from Ramda

> Map Ramda functions to @vinicunca/perkakas, with notes where the APIs differ.

Each heading is a Ramda function. The Perkakas equivalent is checked against `@vinicunca/perkakas` v1.17.1. Names that Remeda documents but Perkakas does not ship are called out. In-page links such as `#reverse` jump to that Ramda section.

## add

Ramda `add` → [`add`](https://vinicunca.dev/perkakas/functions#add).

## addIndex

No direct Perkakas helper. Use the notes below, or native JavaScript.

*Not provided by Perkakas.*

You don't need `addIndex` In Perkakas 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 Perkakas please open
an issue at the Perkakas GitHub project.

```ts
// Ramda
addIndex(map)((val, idx) => `${idx}-${val}`, DATA);

// Perkakas
map(DATA, (val, idx) => `${idx}-${val}`);
```

## allPass

Ramda `allPass` → [`allPass`](https://vinicunca.dev/perkakas/functions#allPass).

## always

Ramda `always` → [`constant`](https://vinicunca.dev/perkakas/functions#constant).

## anyPass

Ramda `anyPass` → [`anyPass`](https://vinicunca.dev/perkakas/functions#anyPass).

## append

Ramda `append` → [`concat`](https://vinicunca.dev/perkakas/functions#concat).

*Not provided by Perkakas.*

- You can replicate this function via the native JS spread `...` operator or via
the Perkakas `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 Perkakas
GitHub project.

```ts
// Ramda
append(operand, DATA);

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

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

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

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

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

## assoc

Ramda `assoc` → [`set`](https://vinicunca.dev/perkakas/functions#set).

## assocPath

Ramda `assocPath` → [`setPath`](https://vinicunca.dev/perkakas/functions#setPath).

## chain

Ramda `chain` → [`flatMap`](https://vinicunca.dev/perkakas/functions#flatMap).

## clamp

Ramda `clamp` → [`clamp`](https://vinicunca.dev/perkakas/functions#clamp).

## clone

Ramda `clone` → [`clone`](https://vinicunca.dev/perkakas/functions#clone).

## complement

Ramda `complement` → [`isNot`](https://vinicunca.dev/perkakas/functions#isNot).

- Unlike Ramda's `complement`, `isNot` preserves type predicates: negating a
type-guard returns a type-guard which *excludes* the guarded type, so the
result of [`filter`](https://vinicunca.dev/perkakas/functions#filter) stays narrowed.
- Ramda's `complement` preserves the arity of the function it wraps, and the
result stays curried. `isNot` only takes a single-parameter predicate and
passes just the first argument through; wrap multi-parameter functions with
the native [logical NOT operator `!`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT)
instead.
- Ramda's `complement` negates the *truthiness* of any return value, whereas
`isNot` requires a predicate that returns a `boolean`. Compose with
[`isTruthy`](https://vinicunca.dev/perkakas/functions#isTruthy) to get the Ramda semantics.

#### Predicates

```ts
// Ramda
complement(predicate);

// Perkakas
isNot(predicate);
```

#### Filtering

```ts
// Ramda
filter(complement(is(String)), DATA);

// Perkakas
filter(DATA, isNot(isString));
```

#### Multiple parameters

```ts
// Ramda
complement(isGreaterThan);

// Native
(a: number, b: number) => !isGreaterThan(a, b);
```

#### Non-boolean predicates

```ts
// Ramda
complement(getLength);

// Perkakas
isNot(piped(getLength, isTruthy));

// Or directly via Native JS:
(data: string) => !getLength(data);
```

## concat

Ramda `concat` → [`concat`](https://vinicunca.dev/perkakas/functions#concat).

## cond

Ramda `cond` → [`conditional`](https://vinicunca.dev/perkakas/functions#conditional).

## countBy

Ramda `countBy` → [`countBy`](https://vinicunca.dev/perkakas/functions#countBy).

## dec

Ramda `dec` → [`subtract`](https://vinicunca.dev/perkakas/functions#subtract).

Use `subtract` with an operand of `1`.

```ts
// Ramda
dec(value);

// Perkakas
subtract(value, 1);
```

## defaultTo

Ramda `defaultTo` → [`defaultTo`](https://vinicunca.dev/perkakas/functions#defaultTo).

- `Number.NaN` is not considered nullish and would not result in returning the
default value. Use [`when`](https://vinicunca.dev/perkakas/functions#when) with the built-in [`Number.isNaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN)
and a [`constant`](https://vinicunca.dev/perkakas/functions#constant) for the fallback value.
- Unlike in Perkakas, Ramda allows the fallback value to be of any type, even
those that are incompatible with the data type. It also allows the data type
to be non-nullish; for those cases use the built-in [Nullish coalescing operator `??`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing)
directly, or use [`when`](https://vinicunca.dev/perkakas/functions#when) with [`isNullish`](https://vinicunca.dev/perkakas/functions#isNullish) and
[`constant`](https://vinicunca.dev/perkakas/functions#constant).

#### Nullish

```ts
const DATA: number | undefined | null;

// Ramda
R.defaultTo(456)(DATA);

// Perkakas
defaultTo(DATA, 456);
```

#### NaN

```ts
const DATA = Number.NaN;

// Ramda
R.defaultTo(10)(DATA);

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

#### Both

```ts
const DATA: number | null | undefined;

// Ramda
R.defaultTo(10)(DATA);

// Perkakas
when(
  DATA,
  (x) => x === undefined || x === null || Number.isNaN(x),
  constant(10),
);
```

#### Non-matching fallback

```ts
const DATA: string | null | undefined;

// Ramda
R.defaultTo(123)(DATA);

// Perkakas
when(DATA, isNullish, constant(123));

// or natively
DATA ?? 123;
```

## difference

Ramda `difference` → [`difference`](https://vinicunca.dev/perkakas/functions#difference).

## differenceWith

Ramda `differenceWith` → [`differenceWith`](https://vinicunca.dev/perkakas/functions#differenceWith).

## divide

Ramda `divide` → [`divide`](https://vinicunca.dev/perkakas/functions#divide).

## drop

Ramda `drop` → [`drop`](https://vinicunca.dev/perkakas/functions#drop).

## dropLast

Ramda `dropLast` → [`dropLast`](https://vinicunca.dev/perkakas/functions#dropLast).

## dropLastWhile

Ramda `dropLastWhile` → [`dropLastWhile`](https://vinicunca.dev/perkakas/functions#dropLastWhile).

## dropWhile

Ramda `dropWhile` → [`dropWhile`](https://vinicunca.dev/perkakas/functions#dropWhile).

## equals

Ramda `equals` → [`isDeepEqual`](https://vinicunca.dev/perkakas/functions#isDeepEqual).

## evolve

Ramda `evolve` → [`evolve`](https://vinicunca.dev/perkakas/functions#evolve).

## F

Ramda `F` → [`constant`](https://vinicunca.dev/perkakas/functions#constant).

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

```ts
// Ramda
F;

// Perkakas
constant(false);
```

## filter

Ramda `filter` → [`filter`](https://vinicunca.dev/perkakas/functions#filter).

## find

Ramda `find` → [`find`](https://vinicunca.dev/perkakas/functions#find).

## findIndex

Ramda `findIndex` → [`findIndex`](https://vinicunca.dev/perkakas/functions#findIndex).

## findLast

Ramda `findLast` → [`findLast`](https://vinicunca.dev/perkakas/functions#findLast).

## findLastIndex

Ramda `findLastIndex` → [`findLastIndex`](https://vinicunca.dev/perkakas/functions#findLastIndex).

## flatten

Ramda `flatten` → [`flat`](https://vinicunca.dev/perkakas/functions#flat).

Unlike `flatten` in Ramda, the Perkakas `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.

```ts
// Ramda
flatten(DATA);

// Perkakas
flat(DATA, 100); // ✅
flat(DATA, Infinity); // ❌
```

## forEach

Ramda `forEach` → [`forEach`](https://vinicunca.dev/perkakas/functions#forEach).

## forEachObjIndexed

Ramda `forEachObjIndexed` → [`forEachObj`](https://vinicunca.dev/perkakas/functions#forEachObj).

## fromPairs

Ramda `fromPairs` → [`fromEntries`](https://vinicunca.dev/perkakas/functions#fromEntries).

## groupBy

Ramda `groupBy` → [`groupBy`](https://vinicunca.dev/perkakas/functions#groupBy).

## has

Ramda `has` → [`hasProp`](https://vinicunca.dev/perkakas/functions#hasProp).

## hasIn

Ramda `hasIn` → [`hasProp`](https://vinicunca.dev/perkakas/functions#hasProp).

- Ramda's `hasIn` uses [the `in` operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in)
which returns `true` for **inherited** properties. Perkakas uses
[`Object.hasOwn`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn)
which ignores them.

#### Own properties

```ts
// Ramda
hasIn('a', obj);

// Perkakas
hasProp(obj, 'a');
```

#### Inherited properties

```ts
// Ramda
hasIn('toString', {}); // => true

// Perkakas
hasProp({}, 'toString'); // => false
```

## head

Ramda `head` → [`first`](https://vinicunca.dev/perkakas/functions#first).

- For strings use [`sliceString`](https://vinicunca.dev/perkakas/functions#sliceString) with `0` and `1` as arguments instead.

#### Arrays

```ts
// Ramda
head([1, 2, 3]);

// Perkakas
first([1, 2, 3]);
```

#### Strings

```ts
// Ramda
head('abc');

// Perkakas
sliceString('abc', 0, 1);
```

## identity

Ramda `identity` → [`identity`](https://vinicunca.dev/perkakas/functions#identity).

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

```ts
// Ramda
map(identity);

// Perkakas
map(identity());
```

## ifElse

Ramda `ifElse` → [`when`](https://vinicunca.dev/perkakas/functions#when).

- Perkakas 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 Perkakas this isn't needed as the extra
arguments would be inferred from the call site.

#### if-else

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

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

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

#### if

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

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

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

#### extra args

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

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

## inc

Ramda `inc` → [`add`](https://vinicunca.dev/perkakas/functions#add).

Use `add` with an operand of `1`.

```ts
// Ramda
inc(value);

// Perkakas
add(value, 1);
```

## includes

Ramda `includes` → [`isIncludedIn`](https://vinicunca.dev/perkakas/functions#isIncludedIn).

- In Ramda `includes` also works on strings; use the native JS
[`String.prototype.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes)
for strings instead.
- Ramda performs a deep equality check for the item, making `includes` useful
for array and object items too. In Perkakas the comparison is performed via the
JS native [`Array.prototype.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes).
For deep equality use the native [`Array.prototype.some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
with Perkakas's [`isDeepEqual`](https://vinicunca.dev/perkakas/functions#isDeepEqual).

#### Arrays

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

// Perkakas
isIncludedIn(1, [1, 2, 3]);
```

#### Strings

```ts
const DATA = 'Hello, World!';

// Perkakas
includes('lo', DATA);

// Native
DATA.includes('lo');
```

#### Object items

```ts
const DATA = [{ name: 'Fred' }];

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

// Perkakas
DATA.some(isDeepEqual({ name: 'Fred' }));
```

#### Array items

```ts
const DATA = [[42]];

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

// Perkakas
DATA.some(isDeepEqual([42]));
```

## indexBy

Ramda `indexBy` → [`indexBy`](https://vinicunca.dev/perkakas/functions#indexBy).

## init

Ramda `init` → [`dropLast`](https://vinicunca.dev/perkakas/functions#dropLast).

- Equivalent to `dropLast` with an argument of `1`.
- On strings use [`sliceString`](https://vinicunca.dev/perkakas/functions#sliceString) with `0` and `-1` as arguments instead.

#### Arrays

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

// Perkakas
dropLast([1, 2, 3], 1);
```

#### Strings

```ts
// Ramda
init('abc');

// Perkakas
sliceString('abc', 0, -1);
```

## innerJoin

Ramda `innerJoin` → [`intersectionWith`](https://vinicunca.dev/perkakas/functions#intersectionWith).

## intersection

Ramda `intersection` → [`intersection`](https://vinicunca.dev/perkakas/functions#intersection).

## invertObj

Ramda `invertObj` → [`invert`](https://vinicunca.dev/perkakas/functions#invert).

## isEmpty

Ramda `isEmpty` → [`isEmptyish`](https://vinicunca.dev/perkakas/functions#isEmptyish).

## isNil

Ramda `isNil` → [`isNullish`](https://vinicunca.dev/perkakas/functions#isNullish).

## isNotNil

Ramda `isNotNil` → [`isNonNullish`](https://vinicunca.dev/perkakas/functions#isNonNullish).

## join

Ramda `join` → [`join`](https://vinicunca.dev/perkakas/functions#join).

## keys

Ramda `keys` → [`keys`](https://vinicunca.dev/perkakas/functions#keys).

## last

Ramda `last` → [`last`](https://vinicunca.dev/perkakas/functions#last).

For strings use [`sliceString`](https://vinicunca.dev/perkakas/functions#sliceString) with `-1` as an argument instead.

#### Arrays

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

// Perkakas
last([1, 2, 3]);
```

#### Strings

```ts
// Ramda
last('abc');

// Perkakas
sliceString('abc', -1);
```

## length

Ramda `length` → [`length`](https://vinicunca.dev/perkakas/functions#length).

## map

Ramda `map` → [`map`](https://vinicunca.dev/perkakas/functions#map).

## mapAccum

Ramda `mapAccum` → [`mapWithFeedback`](https://vinicunca.dev/perkakas/functions#mapWithFeedback).

Perkakas'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`](https://vinicunca.dev/perkakas/functions#last).

```ts
// Ramda
const result = mapAccum((a, b) => [a + b, a + b], 0, ['1', '2', '3', '4']);

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

## mapObjIndexed

Ramda `mapObjIndexed` → [`mapValues`](https://vinicunca.dev/perkakas/functions#mapValues).

## max

No direct Perkakas helper. Use the notes below, or native JavaScript.

*Not provided by Perkakas.*

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

```ts
// Ramda
max(a, b);

// Curried
const maxA = max(a);

// Native
a > b ? a : b;

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

## maxBy

Ramda `maxBy` → [`firstBy`](https://vinicunca.dev/perkakas/functions#firstBy).

The Perkakas `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.

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

// Perkakas
firstBy([a, b], [mapperFunc, 'desc']);
```

## mean

Ramda `mean` → [`mean`](https://vinicunca.dev/perkakas/functions#mean).

## median

Ramda `median` → [`median`](https://vinicunca.dev/perkakas/functions#median).

## mergeAll

Ramda `mergeAll` → [`mergeAll`](https://vinicunca.dev/perkakas/functions#mergeAll).

## mergeDeepRight

Ramda `mergeDeepRight` → [`mergeDeep`](https://vinicunca.dev/perkakas/functions#mergeDeep).

## mergeRight

Ramda `mergeRight` → [`merge`](https://vinicunca.dev/perkakas/functions#merge).

## min

No direct Perkakas helper. Use the notes below, or native JavaScript.

*Not provided by Perkakas.*

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

```ts
// Ramda
min(a, b);

// Curried
const minA = min(a);

// Native
a < b ? a : b;

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

## minBy

Ramda `minBy` → [`firstBy`](https://vinicunca.dev/perkakas/functions#firstBy).

The Perkakas `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.

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

// Perkakas
firstBy([a, b], mapperFunc);
```

## multiply

Ramda `multiply` → [`multiply`](https://vinicunca.dev/perkakas/functions#multiply).

## negate

Ramda `negate` → [`multiply`](https://vinicunca.dev/perkakas/functions#multiply).

Use `multiply` with an operand of `-1`.

```ts
// Ramda
negate(value);

// Perkakas
multiply(value, -1);
```

## not

No direct Perkakas helper. Use the notes below, or native JavaScript.

*Not provided by Perkakas.*

- Use the native [logical NOT operator `!`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT).
- Ramda's `not` is a function, so it can be passed around point-free. The native
operator can't; wrap it in an arrow function.

#### Values

```ts
// Ramda
not(value);

// Native
!value;
```

#### Point-free

```ts
// Ramda
map(not, DATA);

// Perkakas
map(DATA, (value) => !value);
```

## nth

No direct Perkakas helper. Use the notes below, or native JavaScript.

*Not provided by Perkakas.*

- For index `0` use [`first`](https://vinicunca.dev/perkakas/functions#first).
- For index `-1` use [`last`](https://vinicunca.dev/perkakas/functions#last).
- For arbitrary *non-negative* indices use the native JS `data[n]`.
- Or use [`Array.prototype.at`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at) for any index.

```ts
// Ramda
nth(0, DATA);

// Perkakas
first(DATA);

// Ramda
nth(1, DATA);

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

// Ramda
nth(-1, DATA);

// Perkakas
last(DATA);

// Ramda
nth(-2, DATA);

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

## objOf

Ramda `objOf` → [`objOf`](https://vinicunca.dev/perkakas/functions#objOf).

## omit

Ramda `omit` → [`omit`](https://vinicunca.dev/perkakas/functions#omit).

## once

Ramda `once` → [`once`](https://vinicunca.dev/perkakas/functions#once).

## partial

Ramda `partial` → [`partialBind`](https://vinicunca.dev/perkakas/functions#partialBind).

Perkakas's `partialBind` takes a variadic list of arguments instead of an array.

```ts
function greet(greeting, firstName, lastName) {
  return `${greeting} ${firstName} ${lastName}`;
}

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

// Perkakas
partialBind(greet, 'hi', 'john');
```

## partialRight

Ramda `partialRight` → [`partialLastBind`](https://vinicunca.dev/perkakas/functions#partialLastBind).

Perkakas's `partialLastBind` takes a variadic list of arguments instead of an array.

```ts
function greet(greeting, firstName, lastName) {
  return `${greeting} ${firstName} ${lastName}`;
}

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

// Perkakas
partialLastBind(greet, 'john', 'doe');
```

## partition

Ramda `partition` → [`partition`](https://vinicunca.dev/perkakas/functions#partition).

## path

Ramda `path` → [`prop`](https://vinicunca.dev/perkakas/functions#prop).

## pathOr

Ramda `pathOr` → [`prop`](https://vinicunca.dev/perkakas/functions#prop).

Compose [`prop`](https://vinicunca.dev/perkakas/functions#prop) with [`defaultTo`](https://vinicunca.dev/perkakas/functions#defaultTo).

```ts
// Ramda
R.pathOr('N/A', ['a', 'b'], { a: { b: 2 } });

// Perkakas
defaultTo(prop({ a: { b: 2 } }, 'a', 'b'), 'N/A');
```

## paths

Ramda `paths` → [`prop`](https://vinicunca.dev/perkakas/functions#prop).

Compose `paths` using [`map`](https://vinicunca.dev/perkakas/functions#map) and [`prop`](https://vinicunca.dev/perkakas/functions#prop):

```ts
const DATA = { a: { b: 2 }, p: [{ q: 3 }] };
const PATHS = [
  ['a', 'b'],
  ['p', 0, 'q'],
] as const;

// Ramda
R.paths(PATHS, DATA);

// Perkakas
map(PATHS, (path) => prop(DATA, ...path));
```

## pick

Ramda `pick` → [`pick`](https://vinicunca.dev/perkakas/functions#pick).

## pickBy

Ramda `pickBy` → [`pickBy`](https://vinicunca.dev/perkakas/functions#pickBy).

## pipe

Ramda `pipe` → [`pipe`](https://vinicunca.dev/perkakas/functions#pipe).

## pluck

Ramda `pluck` → [`map`](https://vinicunca.dev/perkakas/functions#map).

*Not provided by Perkakas.*

- `pluck(data, k)` is equivalent to `map(data, prop(k))`.
- When data is an **object** (and not an *array*) use `mapValues` instead.

#### Arrays

```ts
const DATA = [{ val: 'hello' }, { val: 'world' }];

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

// Perkakas
map(DATA, prop('val'));
```

#### Objects

```ts
const DATA = { a: { val: 'hello' }, b: { val: 'world' } };

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

// Perkakas
mapValues(DATA, prop('val'));
```

## product

Ramda `product` → [`product`](https://vinicunca.dev/perkakas/functions#product).

## prop

Ramda `prop` → [`prop`](https://vinicunca.dev/perkakas/functions#prop).

## range

Ramda `range` → [`range`](https://vinicunca.dev/perkakas/functions#range).

Perkakas curries functions by stripping the first parameter. This means that
unlike in Ramda, a curried call to `range` would result in a function that has
a pre-set `end` value, and not a pre-set `start` value; curried calls need their
`start` and `end` parameters swapped!

#### Simple

```ts
// Ramda
R.range(10, 20);
R.range(start, end);

// Perkakas
range(10, 20);
range(start, end);
```

#### Curried

```ts
// Ramda
R.range(10)(20);
R.range(start)(end);

// Perkakas
range(20)(10);
range(end)(start);
```

## reduce

Ramda `reduce` → [`reduce`](https://vinicunca.dev/perkakas/functions#reduce).

## reject

Ramda `reject` → [`filter`](https://vinicunca.dev/perkakas/functions#filter).

Wrap the callback with [`isNot`](https://vinicunca.dev/perkakas/functions#isNot).

```ts
// Ramda
reject(predicate, DATA);

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

// Or in a pipe
pipe(DATA, filter(isNot(predicate)));
```

## remove

Ramda `remove` → [`splice`](https://vinicunca.dev/perkakas/functions#splice).

## reverse

Ramda `reverse` → [`reverse`](https://vinicunca.dev/perkakas/functions#reverse).

## set

Ramda `set` → [`set`](https://vinicunca.dev/perkakas/functions#set).

## sort

Ramda `sort` → [`sort`](https://vinicunca.dev/perkakas/functions#sort).

## sortBy

Ramda `sortBy` → [`sortBy`](https://vinicunca.dev/perkakas/functions#sortBy).

## sortWith

Ramda `sortWith` → [`sortBy`](https://vinicunca.dev/perkakas/functions#sortBy).

Perkakas'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.

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

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

// Perkakas
sortBy(DATA, [prop('age'), 'desc'], prop('name'));

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

## split

Ramda `split` → [`split`](https://vinicunca.dev/perkakas/functions#split).

## splitAt

Ramda `splitAt` → [`splitAt`](https://vinicunca.dev/perkakas/functions#splitAt).

## splitWhen

Ramda `splitWhen` → [`splitWhen`](https://vinicunca.dev/perkakas/functions#splitWhen).

## subtract

Ramda `subtract` → [`subtract`](https://vinicunca.dev/perkakas/functions#subtract).

## sum

Ramda `sum` → [`sum`](https://vinicunca.dev/perkakas/functions#sum).

## swap

Ramda `swap` → [`swapIndices`](https://vinicunca.dev/perkakas/functions#swapIndices).

## T

Ramda `T` → [`constant`](https://vinicunca.dev/perkakas/functions#constant).

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

```ts
// Ramda
T;

// Perkakas
constant(true);
```

## tail

Ramda `tail` → [`drop`](https://vinicunca.dev/perkakas/functions#drop).

- Equivalent to `drop` with an argument of `1`.
- On strings use [`sliceString`](https://vinicunca.dev/perkakas/functions#sliceString) instead.

#### Arrays

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

// Perkakas
drop([1, 2, 3], 1);
```

#### Strings

```ts
// Ramda
tail('abc');

// Perkakas
sliceString('abc', 1);
```

## take

Ramda `take` → [`take`](https://vinicunca.dev/perkakas/functions#take).

## takeLast

Ramda `takeLast` → [`takeLast`](https://vinicunca.dev/perkakas/functions#takeLast).

## takeLastWhile

Ramda `takeLastWhile` → [`takeLastWhile`](https://vinicunca.dev/perkakas/functions#takeLastWhile).

## takeWhile

Ramda `takeWhile` → [`takeWhile`](https://vinicunca.dev/perkakas/functions#takeWhile).

## tap

Ramda `tap` → [`tap`](https://vinicunca.dev/perkakas/functions#tap).

## times

Ramda `times` → [`times`](https://vinicunca.dev/perkakas/functions#times).

## toLower

Ramda `toLower` → [`toLowerCase`](https://vinicunca.dev/perkakas/functions#toLowerCase).

## toPairs

Ramda `toPairs` → [`entries`](https://vinicunca.dev/perkakas/functions#entries).

## toUpper

Ramda `toUpper` → [`toUpperCase`](https://vinicunca.dev/perkakas/functions#toUpperCase).

## uniq

Ramda `uniq` → [`unique`](https://vinicunca.dev/perkakas/functions#unique).

## uniqBy

Ramda `uniqBy` → [`uniqueBy`](https://vinicunca.dev/perkakas/functions#uniqueBy).

## uniqWith

Ramda `uniqWith` → [`uniqueWith`](https://vinicunca.dev/perkakas/functions#uniqueWith).

## values

Ramda `values` → [`values`](https://vinicunca.dev/perkakas/functions#values).

## when

Ramda `when` → [`when`](https://vinicunca.dev/perkakas/functions#when).

## where

Ramda `where` → [`hasSubObject`](https://vinicunca.dev/perkakas/functions#hasSubObject).

## zip

Ramda `zip` → [`zip`](https://vinicunca.dev/perkakas/functions#zip).

## zipObj

No direct Perkakas helper. Use the notes below, or native JavaScript.

*Not provided by Perkakas.*

Compose [`zip`](https://vinicunca.dev/perkakas/functions#zip) and [`fromEntries`](https://vinicunca.dev/perkakas/functions#fromEntries):

```ts
// Ramda
zipObj(keys, values);

// Perkakas
fromEntries(zip(keys, values));
```

## zipWith

Ramda `zipWith` → [`zipWith`](https://vinicunca.dev/perkakas/functions#zipWith).


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
