Package Exports
- rambdax
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (rambdax) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Rambdax
Extended version of Rambda(utility library) - Documentation
Simple example
const R = require("rambdax")
const result = R.compose(
R.filter(val => val>2),
R.flatten,
)([ [1], [2], [3], 4])
console.log(result) // => [3,4]How to use it?
Simple npm i rambdax is sufficient
Differences between Rambda and Ramda
Rambda's equals doesn't protect against circular structures as Ramda.equals does
Rambda's map/filter works only for arrays, while Ramda's map/filter accept also objects
Rambda's type detect async functions. The returned value is
"Async"
Differences between Rambda and Ramdax
Rambdax passthrough all Rambda's methods and introduce some new functions.
The idea of Rambdax is to extend Rambda without worring for Ramda compatability.
API
API part I - Rambdax own methods
all
it("when returns true", () => {
const numArr = [ 0, 1, 2, 3, 4 ]
const fn = val => val > -1
expect(R.all(fn, numArr)).toBeTruthy()
})allPass
const obj = {
a : 1,
b : 2,
}
const conditionArr = [
val => val.a === 1,
val => val.b === 2,
]
expect(
R.allPass(conditionArr, obj)
).toBeTruthy()both
const fn = R.both(
a => a > 10,
a => a < 20
)
fn(15) //=> true
fn(30) //=> falsedebounce
it("", async() => {
let counter = 0
const inc = () => {
counter++
}
const delay = ms => new Promise(resolve => {
setTimeout(resolve, ms)
})
const incWrapped = debounce(inc, 500)
incWrapped()
expect(counter).toBe(0)
await delay(200)
incWrapped()
expect(counter).toBe(0)
await delay(200)
incWrapped()
expect(counter).toBe(0)
await delay(200)
incWrapped()
expect(counter).toBe(0)
await delay(700)
expect(counter).toBe(1)
})either
const fn = R.either(
a => a > 10,
a => a % 2 === 0
)
fn(15) //=> true
fn(6) //=> true
fn(7) //=> falseflip
Switch first and second arguments of provided function
const fn = (a,b) => a-b
const flipped = R.flip(fn)
flipped(4,1) //=> -3intersection
R.intersection([1,2,3,4], [7,6,5,4,3]); //=> [4, 3]isValid
Full copy of json-validity library
const songSchema = {
published: "number",
style: [ "rock", "jazz" ],
title: "string",
}
const song = {
published: 1975,
style: "rock",
title: "In my time of dying",
}
R.isValid(song,songSchema) // => truememoize
describe("memoize", () => {
it("normal function", () => {
let counter = 0
const fn = (a,b) =>{
counter++
return a+b
}
const memoized = R.memoize(fn)
expect(memoized(1,2)).toBe(3)
expect(memoized(1,2)).toBe(3)
expect(memoized(1,2)).toBe(3)
expect(counter).toBe(1)
expect(memoized(2,2)).toBe(4)
expect(counter).toBe(2)
expect(memoized(1,2)).toBe(3)
expect(counter).toBe(2)
})
it("async function", async () => {
let counter = 0
const delay = ms => new Promise(resolve => {
setTimeout(resolve, ms)
})
const fn = async (ms,a,b) => {
await delay(ms)
counter++
return a+b
}
const memoized = R.memoize(fn)
expect(await memoized(100,1,2)).toBe(3)
expect(await memoized(100,1,2)).toBe(3)
expect(await memoized(100,1,2)).toBe(3)
expect(counter).toBe(1)
expect(await memoized(100,2,2)).toBe(4)
expect(counter).toBe(2)
expect(await memoized(100,1,2)).toBe(3)
expect(counter).toBe(2)
})
})mergeAll
const arr = [
{a:1},
{b:2},
{c:3}
]
const expectedResult = {
a:1,
b:2,
c:3
}
expect(R.mergeAll(arr)).toEqual(expectedResult)omitBy
const input = {
a: 1,
b: 2,
c: 3,
d: 4,
}
const fn = val => val < 3
const expectedResult = {
c: 3,
d: 4,
}
expect(R.omitBy(fn, input)).toEqual(expectedResult)once
const addOneOnce = R.once((a, b, c) => a + b + c)
expect(addOneOnce(10,20,30)).toBe(60)
expect(addOneOnce(40)).toEqual(60)pickBy
const input = {
a: 1,
b: 2,
c: 3,
d: 4,
}
const fn = val => val > 2
const expectedResult = {
c: 3,
d: 4,
}
expect(R.pickBy(fn, input)).toEqual(expectedResult)produce
Typing:
R.produce(
fnObject: Object,
inputArgument: any
): ObjectExample:
const conditions = {
foo: a => a > 10,
bar: a => ({baz:a})
}
const result = R.produce(conditions, 7)
const expectedResult = {
foo: false,
bar: {baz: 7}
}
result === expectedResult // => trueDescription
conditions is an object with sync or async functions as values.
Those functions will be used to generate object with conditions's props and
values, which are result of each conditions value when
inputArgument is the input.
race
race(promises: Object): Object
promises is object with thenable values.
The thenables are resolved with Promise.race to object with a single property.
This property is the key of the first resolved(rejected) promise in promises.
const delay = ms => new Promise(resolve => {
setTimeout(() => {
resolve(ms)
}, ms)
})
const promises = {
a : delay(20),
b : delay(10),
}
R.race(promises)
.then(result =>{
// => { a: 10 }
})const delay = ms => new Promise((resolve,reject) => {
setTimeout(() => {
reject(ms)
}, ms)
})
const promises = {
a : delay(1),
b : delay(2),
}
R.race(promises)
.then(console.log)
.catch(err =>{
// => { a: 1 }
})random
const randomResult = R.random(1, 10)
expect(randomResult).toBeLessThanOrEqual(10)
expect(randomResult).toBeGreaterThanOrEqual(1)rangeBy
expect(
R.rangeBy(0, 10, 2)
).toEqual([0, 2, 4, 6, 8, 10])
expect(
R.rangeBy(0, 2, 0.3)
).toEqual([0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])renameProps
Typing:
R.renameProps(
renameObj: Object,
inputObj: Object
): ObjectExample:
const renameObj = {
f: "foo",
b: "bar"
}
const inputObj = {
f:1,
b:2
}
const result = R.renameProps(renameObj, inputObj)
const expectedResult = {
foo:1,
bar:2
}resolve
resolve(promises: Object): Object
promises is object with thenable values.
All the thenables are resolved with Promise.all to object, which
props are the keys of promises and which values are the resolved results.
const delay = ms => new Promise(resolve => {
setTimeout(() => {
resolve(ms)
}, ms)
})
const promises = {
a : delay(1),
b : delay(2),
c : delay(3),
}
const result = await R.resolve(promises)
// => { a:1, b:2, c:3 }tap
tap(fn: Function, inputArgument: T): T
Execute fn with inputArgument as argument and returns inputArgument
const fn = a => console.log(a)
const result = R.tap(fn, "foo")
// logs "foo"
// `result` is "foo"where
where(conditions: Object, obj: Object): Boolean
const condition = R.where({
a : aProp => typeof aProp === "string",
b : bProp => bProp === 4
})
condition({
a : "foo",
b : 4,
c : 11,
}) //=> true
condition({
a : 1,
b : 4,
c : 11,
}) //=> falseMethods inherited from Rambda
add
add(a: Number, b: Number): Number
R.add(2, 3) //=> 5adjust
adjust(replaceFn: Function, i:Number, arr:Array): Array
- Replaces
iindex inarrwith the result ofreplaceFn(arr[i])
R.adjust(a => a + 1, 0, [0, 100]) //=> [1, 100]any
any(condition: Function, arr: Array): Boolean
- Returns true if at least one member of
arrreturns true, when passed to theconditionfunction
R.any(a => a * a > 8)([1, 2, 3]) //=> true
R.any(a => a * a > 10)([1, 2, 3]) //=> falseappend
append(valueToAppend: any, arr: Array): Array
R.append('foo', ['bar', 'baz']) //=> ['foo', 'bar', 'baz']contains
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]) //=> falsecurry
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) // => 10defaultTo
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
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
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
equals(a: any, b: any): Boolean
- Returns equality match between
aandb
Doesn't handles cyclical data structures
R.equals(1, 1) //=> true
R.equals({}, {}) //=> false
R.equals([1, 2, 3], [1, 2, 3]) //=> truefilter
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
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
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) //=> 1flatten
flatten(arr: Array): Array
R.flatten([ 1, [ 2, [ 3 ] ] ]
//=> [ 1, 2, 3 ]has
has(prop: String, obj: Object): Boolean
- Returns
trueifobjhas propertyprop
R.has("a", {a: 1}) //=> true
R.has("b", {a: 1}) //=> falsehead
head(arrOrStr: Array|String): any
- Returns the first element of
arrOrStr
R.head([1, 2, 3]) //=> 1
R.head('foo') //=> 'f'indexOf
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]) //=> 0init
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
join(separator: String, arr: Array): String
R.join('-', [1, 2, 3]) //=> '1-2-3'last
last(arrOrStr: Array|String): any
- Returns the last element of
arrOrStr
R.last(['foo', 'bar', 'baz']) //=> 'baz'
R.last('foo') //=> 'o'length
length(arrOrStr: Array|String): Number
R.length([1, 2, 3]) //=> 3map
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]match
map(regExpression: Regex, str: String): Array
R.match(/([a-z]a)/g, 'bananas') //=> ['ba', 'na', 'na']merge
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
omit(propsToOmit: Array
, obj: Object): Object
- Returns a partial copy of an
objwith omittingpropsToOmit
R.omit(['a', 'd'], {a: 1, b: 2, c: 3}) //=> {b: 2, c: 3}path
path(pathToSearch: Array
, obj: Object): any
- Retrieve the value at
pathToSearchin objectobj
R.path(['a', 'b'], {a: {b: 2}}) //=> 2
R.path(['a', 'c'], {a: {b: 2}}) //=> undefinedpartialCurry
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}) //=> 16Note that
partialCurryis method specific for Rambda and the method is not part of Ramda's APIYou can read my argumentation for creating partialCurry here
pick
pick(propsToPick: Array
, obj: Object): Object
- Returns a partial copy of an
objcontaining onlypropsToPickproperties
R.pick(['a', 'c'], {a: 1, b: 2}) //=> {a: 1}pluck
pluck(property: String, arr: Array): Array
- Returns list of the values of
propertytaken from the objects in array of objectsarr
R.pluck('a')([{a: 1}, {a: 2}, {b: 3}]) //=> [1, 2]prepend
prepend(valueToPrepend: any, arr: Array): Array
R.prepend('foo', ['bar', 'baz']) //=> ['foo', 'bar', 'baz']prop
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}) //=> undefinedpropEq
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}) //=> falserange
range(start: Number, end: Number): Array
- Returns a array of numbers from
start(inclusive) toend(exclusive)
R.range(0, 2) //=> [0, 1]repeat
repeat(valueToRepeat: T, num: Number): Array
R.repeat('foo', 2) //=> ['foo', 'foo']replace
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
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
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
split(separator: String, str: String): Array
R.split('-', 'a-b-c') //=> ['a', 'b', 'c']splitEvery
splitEvery(sliceLength: Number, arrOrString: Array|String): Array
- Splits
arrOrStrinto slices ofsliceLength
R.splitEvery(2, [1, 2, 3]) //=> [[1, 2], [3]]
R.splitEvery(3, 'foobar') //=> ['foo', 'bar']subtract
subtract(a: Number, b: Number): Number
Returns a minus b
R.subtract(3, 1) //=> 2tail
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
take(num: Number, arrOrStr: Array|String): Array|String
- Returns the first
numelements ofarrOrStr
R.take(1, ['foo', 'bar']) //=> ['foo']
R.take(2, ['foo']) //=> 'fo'takeLast
takeLast(num: Number, arrOrStr: Array|String): Array|String
- Returns the last
numelements ofarrOrStr
R.takeLast(1, ['foo', 'bar']) //=> ['bar']
R.takeLast(2, ['foo']) //=> 'oo'test
test(regExpression: Regex, str: String): Boolean
- Determines whether
strmatchesregExpression
R.test(/^f/, 'foo') //=> true
R.test(/^f/, 'bar') //=> falsetoLower
toLower(str: String): String
R.toLower('FOO') //=> 'foo'toUpper
toUpper(str: String): String
R.toUpper('foo') //=> 'FOO'trim
trim(str: String): String
R.trim(' foo ') //=> 'foo'type
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
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
update(i: Number, replaceValue: any, arr: Array): Array
- Returns a new copy of the
arrwith the element atiindex replaced withreplaceValue
R.update(0, "foo", ['bar', 'baz']) //=> ['foo', baz]values
values(obj: Object): Array
- Returns array with of all values in
obj
R.values({a: 1, b: 2}) //=> [1, 2]