Faster alternative to Ramda in just 10kB - Documentation
I admire Ramda as it is great library in what it does, but I used only small part of what it offers.
I wanted to optimize the size of my bundle, but I had already developed Ramda habits.
This lead me to the idea to recreate the funtionality of some Ramda methods and export that as a library.
const R = require("rambda")
const result = R.compose(
R.filter(val => val>2),
R.flatten,
)([ [1], [2], [3], 4])
console.log(result) // => [3,4]
-
Use npm i rambda for Webpack and Node.js
-
For browser usage include in your HTML
https://cdnjs.cloudflare.com/ajax/libs/rambda/0.7.1/webVersion.js
Rambda shadows only small part of the Ramda's API.
A few things to note:
-
Rambda's methods should be compatible with most of the basic Ramda's methods. For more complex and Ramda specific methods(such as R.__), you should expect a mismatch.
-
Rambda's type detect async functions. The returned value is
"Async"
-
Rambda's map/filter work only for arrays, while Ramda's map/filter accept also objects.
-
Rambda's equals doesn't protect against circular structures as Ramda.equals does.
-
Rambda's path accepts both string and array as object path.
-
Rambda is tested for compatability with Ramda.flip, as this method could be useful in some cases.
If you need more Ramda methods, than what Rambda offers, you may check the extended version of Rambda - Rambdax
add(a: Number, b: Number): Number
R.add(2, 3) //=> 5
adjust(replaceFn: Function, i:Number, arr:Array): Array
- Replaces
i
index inarr
with the result ofreplaceFn(arr[i])
R.adjust(a => a + 1, 0, [0, 100]) //=> [1, 100]
any(condition: Function, arr: Array): Boolean
- Returns true if at least one member of
arr
returns true, when passed to thecondition
function
R.any(a => a * a > 8)([1, 2, 3]) //=> true
R.any(a => a * a > 10)([1, 2, 3]) //=> false
append(valueToAppend: any, arr: Array): Array
R.append('foo', ['bar', 'baz']) //=> ['foo', 'bar', 'baz']
compose(fn1: Function, ... , fnN: Function): any
Performs right-to-left function composition
const result = R.compose(
R.map(a => a*2)
R.filter(val => val>2),
)([1, 2, 3, 4])
console.log(result) // => [6, 8]
contains(valueToFind: any, arr: Array): Boolean
Returns true if valueToFind
is part of arr
R.contains(2, [1, 2]) //=> true
R.contains(3, [1, 2]) //=> false
curry(fn: Function): Function
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)
g(4) // => 10
defaultTo(defaultArgument: T, inputArgument: any): T
Returns defaultArgument
if inputArgument
is undefined
or the type of inputArgument
is different of the type of defaultArgument
.
Returns inputArgument
in any other case.
R.defaultTo('foo', undefined) //=> 'foo'
R.defaultTo('foo')('bar') //=> 'bar'
R.defaultTo('foo')(1) //=> 'foo'
drop(howManyToDrop: Number, arrOrStr: Array|String): Array|String
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: Array|String): Array|String
Returns arrOrStr
with howManyToDrop
items dropped from the right
R.dropLast(1, ['foo', 'bar', 'baz']) //=> ['foo', 'bar']
R.dropLast(1, 'foo') //=> 'fo'
equals(a: any, b: any): Boolean
- Returns equality match between
a
andb
Doesn't handles cyclical data structures
R.equals(1, 1) //=> true
R.equals({}, {}) //=> false
R.equals([1, 2, 3], [1, 2, 3]) //=> true
filter(filterFn: Function, arr: Array): Array
Filters arr
throw boolean returning filterFn
const filterFn = a => a % 2 === 0
R.filter(filterFn, [1, 2, 3, 4]) //=> [2, 4]
find(findFn: Function, arr: Array): T|undefined
Returns undefined
or the first element of arr
satisfying findFn
const findFn = a => R.type(a.foo) === "Number"
const arr = [{foo: "bar"}, {foo: 1}]
R.find(findFn, arr) //=> {foo: 1}
findIndex(findFn: Function, arr: Array): Number
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}]
R.find(findFn, arr) //=> 1
flatten(arr: Array): Array
R.flatten([ 1, [ 2, [ 3 ] ] ]
//=> [ 1, 2, 3 ]
has(prop: String, obj: Object): Boolean
- Returns
true
ifobj
has propertyprop
R.has("a", {a: 1}) //=> true
R.has("b", {a: 1}) //=> false
head(arrOrStr: Array|String): any
- Returns the first element of
arrOrStr
R.head([1, 2, 3]) //=> 1
R.head('foo') //=> 'f'
indexOf(valueToFind: any, arr: Array): Number
Returns -1
or the index of the first element of arr
equal of valueToFind
R.indexOf(1, [1, 2]) //=> 0
init(arrOrStr: Array|String): Array|String
- Returns all but the last element of
arrOrStr
R.init([1, 2, 3]) //=> [1, 2]
R.init('foo') //=> 'fo'
join(separator: String, arr: Array): String
R.join('-', [1, 2, 3]) //=> '1-2-3'
last(arrOrStr: Array|String): any
- Returns the last element of
arrOrStr
R.last(['foo', 'bar', 'baz']) //=> 'baz'
R.last('foo') //=> 'o'
length(arrOrStr: Array|String): Number
R.length([1, 2, 3]) //=> 3
map(mapFn: Function, arr: Array): Array
Returns the result of looping through arr
with mapFn
const mapFn = x => x * 2;
R.map(mapFn, [1, 2, 3]) //=> [2, 4, 6]
map(regExpression: Regex, str: String): Array
R.match(/([a-z]a)/g, 'bananas') //=> ['ba', 'na', 'na']
merge(a: Object, b: Object)
Returns result of Object.assign({}, a, b)
R.merge({ 'foo': 0, 'bar': 1 }, { 'foo': 7 })
//=> { 'foo': 7, 'bar': 1 }
omit(propsToOmit: Array, obj: Object): Object
- Returns a partial copy of an
obj
with omittingpropsToOmit
R.omit(['a', 'd'], {a: 1, b: 2, c: 3}) //=> {b: 2, c: 3}
path(pathToSearch: Array|String, obj: Object): any
- Retrieve the value at
pathToSearch
in objectobj
R.path('a.b', {a: {b: 2}}) //=> 2
R.path(['a', 'b'], {a: {b: 2}}) //=> 2
R.path(['a', 'c'], {a: {b: 2}}) //=> undefined
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})
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: Array, obj: Object): Object
- Returns a partial copy of an
obj
containing onlypropsToPick
properties
R.pick(['a', 'c'], {a: 1, b: 2}) //=> {a: 1}
pluck(property: String, arr: Array): Array
- Returns list of the values of
property
taken from the objects in array of objectsarr
R.pluck('a')([{a: 1}, {a: 2}, {b: 3}]) //=> [1, 2]
prepend(valueToPrepend: any, arr: Array): Array
R.prepend('foo', ['bar', 'baz']) //=> ['foo', 'bar', 'baz']
prop(propToFind: String, obj: Object): any
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
Returns true if obj
has property propToFind
and its value is equal to valueToMatch
const propToFind = "foo"
const valueToMatch = 0
R.propEq(propToFind, valueToMatch)({foo: 0}) //=> true
R.propEq(propToFind, valueToMatch)({foo: 1}) //=> false
range(start: Number, end: Number): Array
- Returns a array of numbers from
start
(inclusive) toend
(exclusive)
R.range(0, 2) //=> [0, 1]
reduce(iteratorFn: Function, accumulator: any, array: Array): any
- Returns a single item by iterating through the list, successively calling the iterator function
iteratorFn
and passing it anaccumulator
value and the current value from the array, and then passing the result to the next call.
The iterator function behaves like the native callback of the Array.prototype.reduce
method.
const iteratorFn = (acc, val) => acc + val
R.reduce(iteratorFn, 1, [1, 2, 3]) //=> 7
repeat(valueToRepeat: T, num: Number): Array
R.repeat('foo', 2) //=> ['foo', 'foo']
replace(strOrRegex: String|Regex, replacer: String, str: String): String
Replace 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'
sort(sortFn: Function, arr: Array): Array
Returns copy of arr
sorted by sortFn
sortFn
must return Number
const sortFn = (a, b) => a - b
R.sort(sortFn, [3, 1, 2]) //=> [1, 2, 3]
sortBy(sortFn: Function, arr: Array): Array
Returns copy of arr
sorted by sortFn
sortFn
must return value for comparison
const sortFn = obj => obj.foo
R.sortBy(sortFn, [
{foo: 1},
{foo: 0}
])
//=> [{foo: 0}, {foo: 1}]
split(separator: String, str: String): Array
R.split('-', 'a-b-c') //=> ['a', 'b', 'c']
splitEvery(sliceLength: Number, arrOrString: Array|String): Array
- Splits
arrOrStr
into slices ofsliceLength
R.splitEvery(2, [1, 2, 3]) //=> [[1, 2], [3]]
R.splitEvery(3, 'foobar') //=> ['foo', 'bar']
subtract(a: Number, b: Number): Number
Returns a
minus b
R.subtract(3, 1) //=> 2
tail(arrOrStr: Array|String): Array|String
- Returns all but the first element of
arrOrStr
R.tail([1, 2, 3]) //=> [2, 3]
R.tail('foo') //=> 'oo'
take(num: Number, arrOrStr: Array|String): Array|String
- Returns the first
num
elements ofarrOrStr
R.take(1, ['foo', 'bar']) //=> ['foo']
R.take(2, ['foo']) //=> 'fo'
takeLast(num: Number, arrOrStr: Array|String): Array|String
- Returns the last
num
elements ofarrOrStr
R.takeLast(1, ['foo', 'bar']) //=> ['bar']
R.takeLast(2, ['foo']) //=> 'oo'
test(regExpression: Regex, str: String): Boolean
- Determines whether
str
matchesregExpression
R.test(/^f/, 'foo') //=> true
R.test(/^f/, 'bar') //=> false
toLower(str: String): String
R.toLower('FOO') //=> 'foo'
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('s') //=> "String"
R.type(1) //=> "Number"
R.type(false) //=> "Boolean"
R.type(null) //=> "Null"
R.type(/[A-z]/) //=> "RegExp"
uniq(arr: Array): Array
- Returns a new array containing only one copy of each element in
arr
R.uniq([1, 1, 2, 1]) //=> [1, 2]
R.uniq([1, '1']) //=> [1, '1']
update(i: Number, replaceValue: any, arr: Array): Array
- Returns a new copy of the
arr
with the element ati
index replaced withreplaceValue
R.update(0, "foo", ['bar', 'baz']) //=> ['foo', baz]
values(obj: Object): Array
- Returns array with of all values in
obj
R.values({a: 1, b: 2}) //=> [1, 2]
I haven't tested it fully, but the partial test shows that Ramda definitions can be used.
You need to replace declare module ramda
with declare module rambda
on line 10 and store the file as rambda.js
in your flow-typed folder
Changelog
- 0.7.1 Close issue #7 - add
R.reduce
to the API - 0.7.0 Close issue #5 - change name of
curry
topartialCurry
; add new methodcurry
, which works just like Ramda'scurry
- 0.6.2 Add separate documentation site via
docsify
Projects using Rambda
Articles about Rambda