Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Rambda is a lightweight and fast utility library that provides a variety of functions for functional programming in JavaScript. It is a smaller and faster alternative to Ramda, offering a similar API but with a focus on performance and simplicity.
Currying
Currying is a technique of evaluating functions with multiple arguments, one at a time. Rambda's `curry` function allows you to transform a function so that it can be called with fewer arguments than it expects, returning a new function that takes the remaining arguments.
const R = require('rambda');
const add = R.curry((a, b) => a + b);
const add5 = add(5);
console.log(add5(3)); // 8
Composition
Function composition is the process of combining two or more functions to produce a new function. Rambda's `compose` function allows you to create a pipeline of functions that are executed from right to left.
const R = require('rambda');
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
const addAndMultiply = R.compose(R.multiply(2), R.add(3));
console.log(addAndMultiply(4)); // 14
Cloning
Cloning is the process of creating a deep copy of an object. Rambda's `clone` function allows you to create a deep copy of an object, ensuring that changes to the new object do not affect the original object.
const R = require('rambda');
const obj = {a: 1, b: 2};
const clonedObj = R.clone(obj);
console.log(clonedObj); // {a: 1, b: 2}
Filtering
Filtering is the process of selecting a subset of items from a collection based on a predicate function. Rambda's `filter` function allows you to filter elements in an array or object based on a provided predicate.
const R = require('rambda');
const isEven = n => n % 2 === 0;
const numbers = [1, 2, 3, 4, 5, 6];
const evenNumbers = R.filter(isEven, numbers);
console.log(evenNumbers); // [2, 4, 6]
Mapping
Mapping is the process of transforming each item in a collection using a provided function. Rambda's `map` function allows you to apply a function to each element in an array or object, returning a new array or object with the transformed elements.
const R = require('rambda');
const double = n => n * 2;
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = R.map(double, numbers);
console.log(doubledNumbers); // [2, 4, 6, 8, 10]
Lodash is a popular utility library that provides a wide range of functions for common programming tasks. It is more feature-rich compared to Rambda but also larger in size. Lodash focuses on performance and ease of use, offering a comprehensive set of tools for working with arrays, objects, strings, and more.
Underscore is another utility library that provides a variety of functional programming helpers. It is similar to Lodash but with a smaller footprint and fewer features. Underscore offers a core set of functions for working with collections, arrays, objects, and functions, making it a good choice for projects that need a lightweight utility library.
Ramda is a functional programming library for JavaScript that emphasizes immutability and pure functions. It offers a similar API to Rambda but with a larger set of functions and a focus on functional programming principles. Ramda is more feature-rich but also larger in size compared to Rambda.
Faster alternative to Ramda in just 10kB - Documentation
Currenly Rambda is more tree-shakable than Ramda as you can see in this tree-shaking example.
Rambda is generally more performant than Ramda
as the benchmarks can prove that.
You can clone this repo and run yarn run benchmark all
to see for yourself.
R.path
Standard usage of R.path
is R.path(['a', 'b'], {a: {b: 1} })
.
In Rambda you have the choice to use the more readable dot notation:
R.path('a.b', {a: {b: 1} })
R.pick
and R.omit
Similar to dot notation, but the separator is comma(,
) instead of dot(.
).
R.pick('a,b', {a: 1 , b: 2, c: 3} })
Typescript definitions are included in the library, in comparison to Ramda, where you need to additionally install @types/ramda
.
Rambda partially shadows Ramda's API, which means that you need to check Rambda's documentation to assure that all the methods you need are available.
const R = require('rambda')
const result = R.compose(
R.filter( R.equals( 2 ) ),
R.map( R.add( 1 ) )
)({ a: 1, b: 2, c: 3 })
console.log(result) // => '{a: 2}'
Use yarn add rambda for Webpack
and Node.js
usage
For UMD usage either use ./dist/rambda.umd.js
or the CDN link at
https://cdnjs.cloudflare.com/ajax/libs/rambda/1.0.11/webVersion.js
Rambda's type detect async functions and unresolved Promises
. The returned values are 'Async'
and 'Promise'
.
Rambda's equals doesn't protect against circular structures as Ramda.equals does.
Rambda's map and filter pass object key as second argument when mapping over objects.
Rambda's path accepts dot notation, i.e. 'x.y' same as ['x','y']
Rambda's pick and omit accept comma notation, i.e. 'x,y' same as ['x','y']
Rambda's flip works only for functions expecting two arguments.
Rambda's partialCurry and includes are not part of Ramda API.
Rambda's startsWith/endsWith work only with strings, instead with array and strings.
If you need more Ramda methods in Rambda, you may either submit a
PR
or check the extended version of Rambda - Rambdax
add(a: number, b: number): number
R.add(2, 3) // => 5
addIndex(fn: Function): Function
const mapWithIndex = R.addIndex(R.map)
const result = mapWithIndex(
(val, index) => `${val} - ${index}`,
['A', 'B', 'C']
) // => ['A - 0', 'B - 1', 'C - 2']
adjust(replaceFn: Function, i: number, arr: T[]): T[]
It replaces i
index in arr
with the result of replaceFn(arr[i])
.
R.adjust(
a => a + 1,
0,
[0, 100]
) // => [1, 100]
all(fn: Function, arr: T[]): boolean
It returns true
, if all members of array arr
returns true
, when applied as argument to function fn
.
const arr = [ 0, 1, 2, 3, 4 ]
const fn = x => x > -1
const result = R.all(fn, arr)
// => true
allPass(rules: Function[], input: any): boolean
It returns true
, if all functions of rules
return true
, when input
is their argument.
const input = {
a : 1,
b : 2,
}
const rules = [
x => x.a === 1,
x => x.b === 2,
]
const result = R.allPass(rules, input) // => true
always(x: any): Function
It returns function that always returns x
.
const fn = R.always(7)
console.log(fn())// => 7
any(condition: Function, arr: T[]): boolean
It returns true
, if at least one member of arr
returns true, when passed to the condition
function.
R.any(a => a * a > 8)([1, 2, 3])
// => true
anyPass(conditions: Function[]): Function
const isBig = a => a > 20
const isOdd = a => a % 2 === 1
const result = R.anyPass(
[isBig, isOdd]
)(11)
// => true
append(valueToAppend: T, arr: T[]): T[]
R.append(
'foo',
['bar', 'baz']
) // => ['bar', 'baz', 'foo']
both(firstCondition: Function, secondCondition: Function, input: any): boolean
It returns true
, if both function firstCondition
and function secondCondition
return true
, when input
is their argument.
const fn = R.both(
a => a > 10,
a => a < 20
)
console.log(fn(15)) //=> true
console.log(fn(30)) //=> false
compose(fn1: Function, ... , fnN: Function): any
It performs right-to-left function composition.
const result = R.compose(
R.map(x => x * 2),
R.filter(x => x > 2)
)([1, 2, 3, 4])
// => [6, 8]
complement(fn: Function): Function
It returns complemented
function that accept input
as argument.
The return value of complemented
is the negative boolean value of fn(input)
.
const fn = R.complement(x => !x)
const result = fn(false) // => false
concat(x: T[]|string, y: T[]|string): T[]|string
It returns a new string or array, which is the result of merging x
and y
.
R.concat([1, 2])([3, 4]) // => [1, 2, 3, 4]
R.concat('foo')('bar') // => 'foobar'
contains(valueToFind: T, arr: T[]): boolean
It returns true
, if valueToFind
is part of arr
.
R.contains(2, [1, 2]) // => true
R.contains(3, [1, 2]) // => false
curry(fn: Function): Function
It returns curried version of fn
.
const addFourNumbers = (a, b, c, d) => a + b + c + d
const curriedAddFourNumbers = R.curry(addFourNumbers)
const f = curriedAddFourNumbers(1, 2)
const g = f(3)
const result = g(4) // => 10
dec(x: number): number
It decrements a number.
R.dec(2) // => 1
defaultTo(defaultValue: T, inputArgument: any): T
It returns defaultValue
, if inputArgument
is undefined
, null
or NaN
.
It returns inputArgument
in any other case.
R.defaultTo('foo', undefined) // => 'foo'
R.defaultTo('foo', 'bar') // => 'bar'
dissoc(prop: any, obj: object): object
It returns a new object that does not contain a prop
property.
R.dissoc('b', {a: 1, b: 2, c: 3})
//=> {a: 1, c: 3}
R.divide(71, 100) // => 0.71
drop(howManyToDrop: number, arrOrStr: T[]|string): T[]|String
It returns arrOrStr
with howManyToDrop
items dropped from the left.
R.drop(1, ['foo', 'bar', 'baz']) // => ['bar', 'baz']
R.drop(1, 'foo') // => 'oo'
dropLast(howManyToDrop: number, arrOrStr: T[]|String): T[]|String
It returns arrOrStr
with howManyToDrop
items dropped from the right.
R.dropLast(1, ['foo', 'bar', 'baz']) // => ['foo', 'bar']
R.dropLast(1, 'foo') // => 'fo'
endsWith(x: string, str: string): boolean
R.endsWith(
'bar',
'foo-bar'
) // => true
R.endsWith(
'foo',
'foo-bar'
) // => false
endsWith(firstCondition: Function, secondCondition: Function): Function
R.either(
a => a > 10,
a => a % 2 === 0
)(15) //=> true
equals(a: any, b: any): boolean
It returns equality match between a
and b
.
It doesn't handle cyclical data structures.
R.equals(
[1, {a:2}, [{b:3}]],
[1, {a:2}, [{b:3}]]
) // => true
R.F() // => false
filter(filterFn: Function, x: Array|Object): Array|Object
It filters x
iterable over boolean returning filterFn
.
const filterFn = a => a % 2 === 0
const result = R.filter(filterFn, [1, 2, 3, 4])
// => [2, 4]
The method works with objects as well.
Note that unlike Ramda's filter
, here object keys are passed as second argument to filterFn
.
const result = R.filter((val, prop)=>{
return prop === 'a' || val === 2
}, {a: 1, b: 2, c: 3})
// => {a: 1, b: 2}
find(findFn: Function, arr: T[]): T|undefined
It returns undefined
or the first element of arr
satisfying findFn
.
const findFn = a => R.type(a.foo) === 'Number'
const arr = [{foo: 'bar'}, {foo: 1}]
const result = R.find(findFn, arr)
// => {foo: 1}
findIndex(findFn: Function, arr: T[]): number
It returns -1
or the index of the first element of arr
satisfying findFn
.
const findFn = a => R.type(a.foo) === 'Number'
const arr = [{foo: 'bar'}, {foo: 1}]
const result = R.findIndex(findFn, arr)
// => 1
flatten(arr: any[]): any[]
R.flatten([ 1, [ 2, [ 3 ] ] ])
// => [ 1, 2, 3 ]
flip(fn: Function): Function
It returns function which calls fn
with exchanged first and second argument.
const subtractFlip = R.flip(R.subtract)
const result = subtractFlip(1,7)
// => 6
forEach(fn: Function, arr: Array): Array
It applies function fn
over all members of array arr
and returns arr
.
const sideEffect = {}
const result = R.forEach(
x => sideEffect[`foo${x}`] = x
)([1, 2])
console.log(sideEffect) //=> {foo1 : 1, foo2 : 2}
console.log(result) //=> [1, 2]
Note, that unlike Ramda
's forEach, Rambda's one doesn't dispatch to forEach
method of arr
if arr
has such method.
has(prop: string, obj: Object): boolean
true
if obj
has property prop
.R.has('a', {a: 1}) // => true
R.has('b', {a: 1}) // => false
head(arrOrStr: T[]|string): T|string
It returns the first element of arrOrStr
.
R.head([1, 2, 3]) // => 1
R.head('foo') // => 'f'
identity(x: T): T
It just passes back the supplied arguments.
R.identity(7) // => 7
ifElse(condition: Function|boolean, ifFn: Function, elseFn: Function): Function
It returns function, which expect input
as argument and returns finalResult
.
When this function is called, a value answer
is generated as a result of condition(input)
.
If answer
is true
, then finalResult
is equal to ifFn(input)
.
If answer
is false
, then finalResult
is equal to elseFn(input)
.
const fn = R.ifElse(
x => x > 10,
x => x*2,
x => x*10
)
const result = fn(8)
// => 80
inc(x: number): number
It increments a number.
R.inc(1) // => 2
includes(x: any, arrOrStr: T[]|string): boolean
R.includes(1, [1, 2]) // => true
R.includes('oo', 'foo') // => true
R.includes('z', 'foo') // => false
!! Note that this method is not part of Ramda
API.
indexOf(valueToFind: any, arr: T[]): number
It returns -1
or the index of the first element of arr
equal of valueToFind
.
R.indexOf(1, [1, 2]) // => 0
R.indexOf(0, [1, 2]) // => -1
init(arrOrStr: T[]|string): T[]|string
arrOrStr
.R.init([1, 2, 3]) // => [1, 2]
R.init('foo') // => 'fo'
join(separator: string, arr: T[]): string
R.join('-', [1, 2, 3]) // => '1-2-3'
is(xPrototype: any, x: any): boolean
It returns true
is x
is instance of xPrototype
.
R.is(String, 'foo') // => true
R.is(Array, 1) // => false
isNil(x: any): boolean
It returns true
is x
is either null
or undefined
.
R.isNil(null) // => true
R.isNil(1) // => false
last(arrOrStr: T[]|string): T|string
arrOrStr
.R.last(['foo', 'bar', 'baz']) // => 'baz'
R.last('foo') // => 'o'
lastIndexOf(x: any, arr: T[]): number
It returns the last index of x
in array arr
.
R.equals
is used to determine equality between x
and members of arr
.
Value -1
is returned if no x
is found in arr
.
R.lastIndexOf(1, [1, 2, 3, 1, 2]) // => 3
R.lastIndexOf(10, [1, 2, 3, 1, 2]) // => -1
length(arrOrStr: Array|String): Number
R.length([1, 2, 3]) // => 3
map(mapFn: Function, x: Array|Object): Array|Object
It returns the result of looping through iterable x
with mapFn
.
The method works with objects as well.
Note that unlike Ramda's map
, here object keys are passed as second argument to mapFn
.
const mapFn = x => x * 2
const resultWithArray = R.map(mapFn, [1, 2, 3])
// => [2, 4, 6]
const result = R.map((val, prop)=>{
return `${val}-${prop}`
}, {a: 1, b: 2})
// => {a: 'a-1', b: 'b-2'}
match(regExpression: Regex, str: string): string[]
R.match(/([a-z]a)/g, 'bananas') // => ['ba', 'na', 'na']
merge(a: Object, b: Object)
It returns result of Object.assign({}, a, b)
.
R.merge({ 'foo': 0, 'bar': 1 }, { 'foo': 7 })
// => { 'foo': 7, 'bar': 1 }
modulo(a: number, b: number):numberNumber
It returns the remainder of operation a/b
.
R.module(14, 3) // => 2
multiply(a: number, b: number): number
It returns the result of operation a*b
.
R.multiply(4, 3) // => 12
not(x: any): boolean
It returns inverted boolean version of input x
.
R.not(true) //=> false
R.not(false) //=> true
R.not(0) //=> true
R.not(1) //=> false
omit(propsToOmit: string[]|string, obj: Object): Object
It returns a partial copy of an obj
with omitting propsToOmit
R.omit('a,c,d', {a: 1, b: 2, c: 3}) // => {b: 2}
path(pathToSearch: string[]|string, obj: Object): any
If pathToSearch
is 'a.b'
then it will return 1
if obj
is {a:{b:1}}
.
It will return undefined
, if such path is not found.
R.path('a.b', {a: {b: 1}}) // => 1
pathOr(defaultValue: any, pathToSearch: string[]|string, obj: Object): any
pathFound
is the result of calling R.path(pathToSearch, obj)
.
If pathFound
is undefined
, null
or NaN
, then defaultValue
will be returned.
pathFound
is returned in any other case.
R.pathOr(1, 'a.b', {a: {b: 2}}) // => 2
R.pathOr(1, ['a', 'b'], {a: {b: 2}}) // => 2
R.pathOr(1, ['a', 'c'], {a: {b: 2}}) // => 1
partialCurry(fn: Function|Async, a: Object, b: Object): Function|Promise
When called with function fn
and first set of input a
, it will return a function.
This function will wait to be called with second set of input b
and it will invoke fn
with the merged object of a
over b
.
fn
can be asynchronous function. In that case a Promise
holding the result of fn
is returned.
See the example below:
const fn = ({a, b, c}) => {
return (a * b) + c
}
const curried = R.partialCurry(fn, {a: 2})
const result = curried({b: 3, c: 10})
// => 16
Note that partialCurry
is method specific for Rambda and the method is not part of Ramda's API
You can read my argumentation for creating partialCurry here
pick(propsToPick: string[], obj: Object): Object
It returns a partial copy of an obj
containing only propsToPick
properties.
R.pick(['a', 'c'], {a: 1, b: 2}) // => {a: 1}
pipe(fn1: Function, ... , fnN: Function): any
It performs left-to-right function composition.
const result = R.pipe(
R.filter(val => val > 2),
R.map(a => a * 2)
)([1, 2, 3, 4])
// => [6, 8]
pluck(property: string, arr: Object[]): any[]
It returns list of the values of property
taken from the objects in array of objects arr
.
R.pluck('a')([{a: 1}, {a: 2}, {b: 3}]) // => [1, 2]
prepend(x: T, arr: T[]): T[]
It adds x
to the start of the array arr
.
R.prepend('foo', ['bar', 'baz']) // => ['foo', 'bar', 'baz']
prop(propToFind: string, obj: Object): any
It returns undefined
or the value of property propToFind
in obj
R.prop('x', {x: 100}) // => 100
R.prop('x', {a: 1}) // => undefined
propEq(propToFind: string, valueToMatch: any, obj: Object): boolean
It returns true if obj
has property propToFind
and its value is equal to valueToMatch
.
const propToFind = 'foo'
const valueToMatch = 0
const result = R.propEq(propToFind, valueToMatch)({foo: 0})
// => true
range(start: number, end: number): number[]
It returns a array of numbers from start
(inclusive) to end
(exclusive).
R.range(0, 3) // => [0, 1, 2]
reduce(iteratorFn: Function, accumulator: any, array: T[]): any
const iteratorFn = (acc, val) => acc + val
const result = R.reduce(iteratorFn, 1, [1, 2, 3])
// => 7
reject(fn: Function, arr: T[]): T[]
It has the opposite effect of R.filter
.
It will return those members of arr
that return false
when applied to function fn
.
const fn = x => x % 2 === 1
const result = R.reject(fn, [1, 2, 3, 4])
// => [2, 4]
repeat(valueToRepeat: T, num: number): T[]
R.repeat('foo', 2) // => ['foo', 'foo']
replace(strOrRegex: string|Regex, replacer: string, str: string): string
It replaces strOrRegex
found in str
with replacer
.
R.replace('foo', 'bar', 'foo foo') // => 'bar foo'
R.replace(/foo/, 'bar', 'foo foo') // => 'bar foo'
R.replace(/foo/g, 'bar', 'foo foo') // => 'bar bar'
reverse(str: T[]): T[]
const arr = [1, 2]
const result = R.reverse(arr)
// => [2, 1]
takeLast(num: number, arrOrStr: T[]|string): T[]|String
It returns copy of arr
sorted by sortFn
.
Note that sortFn
must return a number type.
const sortFn = (a, b) => a - b
const result = R.sort(sortFn, [3, 1, 2])
// => [1, 2, 3]
sortBy(sortFn: Function, arr: T[]): T[]
It returns copy of arr
sorted by sortFn
.
sortFn
must return value for comparison
const sortFn = obj => obj.foo
const result = R.sortBy(sortFn, [
{foo: 1},
{foo: 0}
])
const expectedResult = [ {foo: 0}, {foo: 1} ]
console.log(result === expectedResult) // => true
split(separator: string, str: string): string[]
R.split('-', 'a-b-c') // => ['a', 'b', 'c']
splitEvery(sliceLength: number, arrOrString: T[]|string): T[T[]]|string[]
arrOrStr
into slices of sliceLength
.R.splitEvery(2, [1, 2, 3]) // => [[1, 2], [3]]
R.splitEvery(3, 'foobar') // => ['foo', 'bar']
startsWith(x: string, str: string): boolean
R.startsWith(
'foo',
'foo-bar'
) // => true
R.startsWith(
'bar',
'foo-bar'
) // => false
subtract(a: number, b: number): number
R.subtract(3, 1) // => 2
R.T() // => true
tail(arrOrStr: T[]|string): T[]|string
arrOrStr
R.tail([1, 2, 3]) // => [2, 3]
R.tail('foo') // => 'oo'
take(num: number, arrOrStr: T[]|string): T[]|string
num
elements of arrOrStr
.R.take(1, ['foo', 'bar']) // => ['foo']
R.take(2, ['foo']) // => 'fo'
takeLast(num: number, arrOrStr: T[]|string): T[]|string
num
elements of arrOrStr
.R.takeLast(1, ['foo', 'bar']) // => ['bar']
R.takeLast(2, ['foo']) // => 'oo'
test(regExpression: Regex, str: string): boolean
str
matches regExpression
R.test(/^f/, 'foo')
// => true
times(fn: Function, n: number): T[]
It returns the result of applying function fn
over members of range array.
The range array includes numbers between 0
and n
(exclusive).
R.times(R.identity, 5)
//=> [0, 1, 2, 3, 4]
toLower(str: string): string
R.toLower('FOO') // => 'foo'
toString(x: any): string
R.toString([1, 2]) // => '1,2'
toUpper(str: string): string
R.toUpper('foo') // => 'FOO'
trim(str: string): string
R.trim(' foo ') // => 'foo'
type(a: any): string
R.type(() => {}) // => 'Function'
R.type(async () => {}) // => 'Async'
R.type([]) // => 'Array'
R.type({}) // => 'Object'
R.type('foo') // => 'String'
R.type(1) // => 'Number'
R.type(true) // => 'Boolean'
R.type(null) // => 'Null'
R.type(/[A-z]/) // => 'RegExp'
const delay = ms => new Promise(resolve => {
setTimeout(function () {
resolve()
}, ms)
})
R.type(delay) // => 'Promise'
uniq(arr: T[]): T[]
It returns a new array containing only one copy of each element in arr
.
R.uniq([1, 1, 2, 1])
// => [1, 2]
uniqWith(fn: Function, arr: T[]): T[]
It returns a new array containing only one copy of each element in arr
according to boolean returning function fn
.
const arr = [
{id: 0, title:'foo'},
{id: 1, title:'bar'},
{id: 2, title:'baz'},
{id: 3, title:'foo'},
{id: 4, title:'bar'},
]
const expectedResult = [
{id: 0, title:'foo'},
{id: 1, title:'bar'},
{id: 2, title:'baz'},
]
const fn = (x,y) => x.title === y.title
const result = R.uniqWith(fn, arr)
console.log(result === expectedResult) // => true
update(i: number, replaceValue: T, arr: T[]): T[]
It returns a new copy of the arr
with the element at i
index
replaced with replaceValue
.
R.update(0, 'foo', ['bar', 'baz'])
// => ['foo', baz]
values(obj: Object): Array
It returns array with of all values in obj
.
R.values({a: 1, b: 2})
// => [1, 2]
without(a: T[], b: T[]): T[]
It will return a new array based on b
array.
This array contains all members of b
array, that doesn't exist in a
array.
Method R.equals
is used to determine the existance of b
members in a
array.
R.without([1, 2], [1, 2, 3, 4])
// => [3, 4]
import omit from 'rambda/lib/omit'
R.equals
R.map
and R.filter
pass object properties when mapping over objectsR.uniqWith
R.pipe
typingsR.ifElse
accept also boolean as condition argumenttypedDefaultTo
and typedPathOr
| Add R.pickAll
and R.none
Rambda
fully tree-shakeable| Edit Typescript definitionRollup
tree-shake | Remove R.padEnd
and R.padStart
R.reverse
mutates the arrayR.reject
and R.without
(PR#41 PR#42) | Remove 'browser' field in package.json
due to Webpack bug 4674R.forEach
and R.times
Typescript
definitionsdefaultTo
to a new method typedDefaultTo
; make defaultTo
follow Ramda spec; add pathOr
; add typedPathOr
.R.pipe
PR#35R.isNil
Webpack
with Rollup
- PR29R.tap
and R.identity
R.all
, R.allPass
, R.both
, R.either
and R.complement
yarn test
before yarn publish
the hard wayR.always
, R.T
and R.F
concat
, padStart
, padEnd
, lastIndexOf
, toString
, reverse
, endsWith
and startsWith
methodsR.ifElse
R.not
, R.includes
| Take string as condition for R.pick
and R.omit
R.values
R.omit
R.curry
, which used to return incorrectly function
when called with more argumentses2015
; Approve PR #10 - add R.addIndex
to the APIPromise
support for R.type
R.reduce
to the APIcurry
to partialCurry
; add new method curry
, which works just like Ramda's curry
docsify
Running benchmarks
yarn run benchmark all
yarn run benchmark add compose filter
Libraries using Rambda
Articles about Rambda
FAQs
Lightweight and faster alternative to Ramda with included TS definitions
The npm package rambda receives a total of 551,776 weekly downloads. As such, rambda popularity was classified as popular.
We found that rambda demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.