All Projects → remeda → Remeda

remeda / Remeda

Licence: mit
A utility library for JavaScript and TypeScript.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Remeda

Pareto.js
An extremely small, intuitive and fast functional utility library for JavaScript
Stars: ✭ 254 (-67.18%)
Mutual labels:  utility, functional
Funky
Funky is a functional utility library written in Objective-C.
Stars: ✭ 41 (-94.7%)
Mutual labels:  utility, functional
Lens
A utility for working with nested data structures.
Stars: ✭ 104 (-86.56%)
Mutual labels:  utility, functional
Arare
Lightweight curried functional programming library
Stars: ✭ 127 (-83.59%)
Mutual labels:  programming, functional
Haxor News
Browse Hacker News like a haxor: A Hacker News command line interface (CLI).
Stars: ✭ 3,342 (+331.78%)
Mutual labels:  utility, programming
rudash
Rudash - Lodash for Ruby Apps
Stars: ✭ 27 (-96.51%)
Mutual labels:  utility, functional
polyrpc
PolyRPC, A multi-tier functional programming language
Stars: ✭ 16 (-97.93%)
Mutual labels:  functional, programming
Saws
A supercharged AWS command line interface (CLI).
Stars: ✭ 4,886 (+531.27%)
Mutual labels:  utility, programming
Swiftz-Validation
A data structure for validations. It implements the applicative functor interface
Stars: ✭ 15 (-98.06%)
Mutual labels:  functional, programming
mimsa
small programming language. pls be gentle.
Stars: ✭ 23 (-97.03%)
Mutual labels:  functional, programming
Observable
The easiest way to observe values in Swift.
Stars: ✭ 346 (-55.3%)
Mutual labels:  programming, functional
Pydash
The kitchen sink of Python utility libraries for doing "stuff" in a functional way. Based on the Lo-Dash Javascript library.
Stars: ✭ 728 (-5.94%)
Mutual labels:  utility, functional
Result
The modelling for success/failure of operations in Kotlin
Stars: ✭ 705 (-8.91%)
Mutual labels:  functional
Reloading
Change Python code while it's running without losing state
Stars: ✭ 723 (-6.59%)
Mutual labels:  utility
Goto
Alias and navigate to directories with tab completion in Linux
Stars: ✭ 698 (-9.82%)
Mutual labels:  utility
Backslide
💦 CLI tool for making HTML presentations with Remark.js using Markdown
Stars: ✭ 679 (-12.27%)
Mutual labels:  utility
Sinuous
🧬 Light, fast, reactive UI library
Stars: ✭ 740 (-4.39%)
Mutual labels:  functional
Syntax sugar python
A library adding some anti-Pythonic syntatic sugar to Python
Stars: ✭ 721 (-6.85%)
Mutual labels:  functional
P1xt Guides
Programming curricula
Stars: ✭ 6,054 (+682.17%)
Mutual labels:  programming
Thor
Switch the right application ASAP.
Stars: ✭ 660 (-14.73%)
Mutual labels:  utility

Remeda

The first "data-first" and "data-last" utility library designed especially for TypeScript.

Build Status npm module dependencies

Installation

npm i remeda
yarn add remeda

Then in .js or .ts

import * as R from 'remeda'; // tree-shaking supported!

Why Remeda?

There are no good utility libraries that work well with TypeScript. When working with Lodash or Ramda you must sometimes annotate types manually.
Remeda is written and tested in TypeScript and that means there won't be any problems with custom typings.

What's "data-first" and "data-last"?

Functional programming is nice, and it makes the code more readable. However there are situations where you don't need "pipes", and you want to call just a single function.

// Remeda
R.pick(obj, ['firstName', 'lastName']);

// Ramda
R.pick(['firstName', 'lastName'], obj);

// Lodash
_.pick(obj, ['firstName', 'lastName']);

In the above example, "data-first" approach is more natural and more programmer friendly because when you type the second argument, you get the auto-complete from IDE. It's not possible to get the auto-complete in Ramda because the data argument is not provided.

"data-last" approach is helpful when writing data transformations aka pipes.

const users = [
  {name: 'john', age: 20, gender: 'm'},
  {name: 'marry', age: 22, gender: 'f'},
  {name: 'samara', age: 24, gender: 'f'},
  {name: 'paula', age: 24, gender: 'f'},
  {name: 'bill', age: 33, gender: 'm'},
]

// Remeda
R.pipe(
  users,
  R.filter(x => x.gender === 'f'),
  R.groupBy(x => x.age),
);

// Ramda
R.pipe(
  R.filter(x => x.gender === 'f'),
  R.groupBy(x => x.age),
)(users) // broken typings in TS :(

// Lodash
_(users)
  .filter(x => x.gender === 'f')
  .groupBy(x => x.age)
  .value()

// Lodash-fp
_.flow(
  _.filter(x => x.gender === 'f'),
  _.groupBy(x => x.age),
)(users)// broken typings in TS :(

Mixing paradigms can be cumbersome in Lodash because it requires importing two different methods.
Remeda implements all methods in two versions, and the correct overload is picked based on the number of provided arguments.
The "data-last" version must always have one argument less than the "data-first" version.

// Remeda
R.pick(obj, ['firstName', 'lastName']); // data-first
R.pipe(obj, R.pick(['firstName', 'lastName'])); // data-last

R.pick(['firstName', 'lastName'], obj); // error, this won't work!
R.pick(['firstName', 'lastName'])(obj); // this will work but the types cannot be inferred

Lazy evaluation

Many functions support lazy evaluation when using pipe or createPipe. These functions have a pipeable tag in the documentation.
Lazy evaluation is not supported in Ramda and only partially supported in lodash.

// Get first 3 unique values
const arr = [1, 2, 2, 3, 3, 4, 5, 6];

const result = R.pipe(
  arr,                    // only four iterations instead of eight (array.length)
  R.map(x => {
    console.log('iterate', x);
    return x;
  }),
  R.uniq(),
  R.take(3)
); // => [1, 2, 3]

/**
 * Console output:
 * iterate 1
 * iterate 2
 * iterate 2
 * iterate 3
 * /

Indexed version

Iterable functions have an extra property indexed which is the same function with iterator (element, index, array).

const arr = [10, 12, 13, 3];

// filter even values
R.filter(arr, x => x % 2 === 0); // => [10, 12]

// filter even indexes
R.filter.indexed(arr, (x, i) => i % 2 === 0); // => [10, 13]

For Lodash and Ramda users

Please check function mapping in mapping.md.

Remeda Design Goals

  1. The usage must be programmer friendly, and that's more important than following XYZ paradigm strictly.
  2. Manual annotation should never be required, and proper typings should infer everything. The only exception is the first function in createPipe.
  3. E6 polyfill is required. Core methods are reused, and data structure (like Map/Set) are not re-implemented.
  4. The implementation of each function should be as minimal as possible. Tree-shaking is supported by default. (Do you know that lodash.keyBy has 14KB after minification?)
  5. All functions are immutable, and there are no side-effects.
  6. Fixed number of arguments.

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].