mirror of https://gitee.com/bigwinds/arangodb
7786 lines
262 KiB
JavaScript
7786 lines
262 KiB
JavaScript
// Ramda v0.15.1
|
|
// https://github.com/ramda/ramda
|
|
// (c) 2013-2015 Scott Sauyet, Michael Hurley, and David Chambers
|
|
// Ramda may be freely distributed under the MIT license.
|
|
|
|
;(function() {
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* A special placeholder value used to specify "gaps" within curried functions,
|
|
* allowing partial application of any combination of arguments,
|
|
* regardless of their positions.
|
|
*
|
|
* If `g` is a curried ternary function and `_` is `R.__`, the following are equivalent:
|
|
*
|
|
* - `g(1, 2, 3)`
|
|
* - `g(_, 2, 3)(1)`
|
|
* - `g(_, _, 3)(1)(2)`
|
|
* - `g(_, _, 3)(1, 2)`
|
|
* - `g(_, 2, _)(1, 3)`
|
|
* - `g(_, 2)(1)(3)`
|
|
* - `g(_, 2)(1, 3)`
|
|
* - `g(_, 2)(_, 3)(1)`
|
|
*
|
|
* @constant
|
|
* @memberOf R
|
|
* @category Function
|
|
* @example
|
|
*
|
|
* var greet = R.replace('{name}', R.__, 'Hello, {name}!');
|
|
* greet('Alice'); //=> 'Hello, Alice!'
|
|
*/
|
|
var __ = { '@@functional/placeholder': true };
|
|
|
|
var _add = function _add(a, b) {
|
|
return a + b;
|
|
};
|
|
|
|
var _all = function _all(fn, list) {
|
|
var idx = 0;
|
|
while (idx < list.length) {
|
|
if (!fn(list[idx])) {
|
|
return false;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
var _any = function _any(fn, list) {
|
|
var idx = 0;
|
|
while (idx < list.length) {
|
|
if (fn(list[idx])) {
|
|
return true;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
var _assoc = function _assoc(prop, val, obj) {
|
|
var result = {};
|
|
for (var p in obj) {
|
|
result[p] = obj[p];
|
|
}
|
|
result[prop] = val;
|
|
return result;
|
|
};
|
|
|
|
var _cloneRegExp = function _cloneRegExp(pattern) {
|
|
return new RegExp(pattern.source, (pattern.global ? 'g' : '') + (pattern.ignoreCase ? 'i' : '') + (pattern.multiline ? 'm' : '') + (pattern.sticky ? 'y' : '') + (pattern.unicode ? 'u' : ''));
|
|
};
|
|
|
|
var _complement = function _complement(f) {
|
|
return function () {
|
|
return !f.apply(this, arguments);
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Basic, right-associative composition function. Accepts two functions and returns the
|
|
* composite function; this composite function represents the operation `var h = f(g(x))`,
|
|
* where `f` is the first argument, `g` is the second argument, and `x` is whatever
|
|
* argument(s) are passed to `h`.
|
|
*
|
|
* This function's main use is to build the more general `compose` function, which accepts
|
|
* any number of functions.
|
|
*
|
|
* @private
|
|
* @category Function
|
|
* @param {Function} f A function.
|
|
* @param {Function} g A function.
|
|
* @return {Function} A new function that is the equivalent of `f(g(x))`.
|
|
* @example
|
|
*
|
|
* var double = function(x) { return x * 2; };
|
|
* var square = function(x) { return x * x; };
|
|
* var squareThenDouble = _compose(double, square);
|
|
*
|
|
* squareThenDouble(5); //≅ double(square(5)) => 50
|
|
*/
|
|
var _compose = function _compose(f, g) {
|
|
return function () {
|
|
return f.call(this, g.apply(this, arguments));
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Private `concat` function to merge two array-like objects.
|
|
*
|
|
* @private
|
|
* @param {Array|Arguments} [set1=[]] An array-like object.
|
|
* @param {Array|Arguments} [set2=[]] An array-like object.
|
|
* @return {Array} A new, merged array.
|
|
* @example
|
|
*
|
|
* _concat([4, 5, 6], [1, 2, 3]); //=> [4, 5, 6, 1, 2, 3]
|
|
*/
|
|
var _concat = function _concat(set1, set2) {
|
|
set1 = set1 || [];
|
|
set2 = set2 || [];
|
|
var idx;
|
|
var len1 = set1.length;
|
|
var len2 = set2.length;
|
|
var result = [];
|
|
idx = 0;
|
|
while (idx < len1) {
|
|
result[result.length] = set1[idx];
|
|
idx += 1;
|
|
}
|
|
idx = 0;
|
|
while (idx < len2) {
|
|
result[result.length] = set2[idx];
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
var _containsWith = function _containsWith(pred, x, list) {
|
|
var idx = 0, len = list.length;
|
|
while (idx < len) {
|
|
if (pred(x, list[idx])) {
|
|
return true;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
var _createMapEntry = function _createMapEntry(key, val) {
|
|
var obj = {};
|
|
obj[key] = val;
|
|
return obj;
|
|
};
|
|
|
|
/**
|
|
* Create a function which takes a comparator function and a list
|
|
* and determines the winning value by a compatator. Used internally
|
|
* by `R.maxBy` and `R.minBy`
|
|
*
|
|
* @private
|
|
* @param {Function} compatator a function to compare two items
|
|
* @category Math
|
|
* @return {Function}
|
|
*/
|
|
var _createMaxMinBy = function _createMaxMinBy(comparator) {
|
|
return function (valueComputer, list) {
|
|
if (!(list && list.length > 0)) {
|
|
return;
|
|
}
|
|
var idx = 1;
|
|
var winner = list[idx];
|
|
var computedWinner = valueComputer(winner);
|
|
var computedCurrent;
|
|
while (idx < list.length) {
|
|
computedCurrent = valueComputer(list[idx]);
|
|
if (comparator(computedCurrent, computedWinner)) {
|
|
computedWinner = computedCurrent;
|
|
winner = list[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
return winner;
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Optimized internal two-arity curry function.
|
|
*
|
|
* @private
|
|
* @category Function
|
|
* @param {Function} fn The function to curry.
|
|
* @return {Function} The curried function.
|
|
*/
|
|
var _curry1 = function _curry1(fn) {
|
|
return function f1(a) {
|
|
if (arguments.length === 0) {
|
|
return f1;
|
|
} else if (a != null && a['@@functional/placeholder'] === true) {
|
|
return f1;
|
|
} else {
|
|
return fn(a);
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Optimized internal two-arity curry function.
|
|
*
|
|
* @private
|
|
* @category Function
|
|
* @param {Function} fn The function to curry.
|
|
* @return {Function} The curried function.
|
|
*/
|
|
var _curry2 = function _curry2(fn) {
|
|
return function f2(a, b) {
|
|
var n = arguments.length;
|
|
if (n === 0) {
|
|
return f2;
|
|
} else if (n === 1 && a != null && a['@@functional/placeholder'] === true) {
|
|
return f2;
|
|
} else if (n === 1) {
|
|
return _curry1(function (b) {
|
|
return fn(a, b);
|
|
});
|
|
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true && b != null && b['@@functional/placeholder'] === true) {
|
|
return f2;
|
|
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true) {
|
|
return _curry1(function (a) {
|
|
return fn(a, b);
|
|
});
|
|
} else if (n === 2 && b != null && b['@@functional/placeholder'] === true) {
|
|
return _curry1(function (b) {
|
|
return fn(a, b);
|
|
});
|
|
} else {
|
|
return fn(a, b);
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Optimized internal three-arity curry function.
|
|
*
|
|
* @private
|
|
* @category Function
|
|
* @param {Function} fn The function to curry.
|
|
* @return {Function} The curried function.
|
|
*/
|
|
var _curry3 = function _curry3(fn) {
|
|
return function f3(a, b, c) {
|
|
var n = arguments.length;
|
|
if (n === 0) {
|
|
return f3;
|
|
} else if (n === 1 && a != null && a['@@functional/placeholder'] === true) {
|
|
return f3;
|
|
} else if (n === 1) {
|
|
return _curry2(function (b, c) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true && b != null && b['@@functional/placeholder'] === true) {
|
|
return f3;
|
|
} else if (n === 2 && a != null && a['@@functional/placeholder'] === true) {
|
|
return _curry2(function (a, c) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else if (n === 2 && b != null && b['@@functional/placeholder'] === true) {
|
|
return _curry2(function (b, c) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else if (n === 2) {
|
|
return _curry1(function (c) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else if (n === 3 && a != null && a['@@functional/placeholder'] === true && b != null && b['@@functional/placeholder'] === true && c != null && c['@@functional/placeholder'] === true) {
|
|
return f3;
|
|
} else if (n === 3 && a != null && a['@@functional/placeholder'] === true && b != null && b['@@functional/placeholder'] === true) {
|
|
return _curry2(function (a, b) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else if (n === 3 && a != null && a['@@functional/placeholder'] === true && c != null && c['@@functional/placeholder'] === true) {
|
|
return _curry2(function (a, c) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else if (n === 3 && b != null && b['@@functional/placeholder'] === true && c != null && c['@@functional/placeholder'] === true) {
|
|
return _curry2(function (b, c) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else if (n === 3 && a != null && a['@@functional/placeholder'] === true) {
|
|
return _curry1(function (a) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else if (n === 3 && b != null && b['@@functional/placeholder'] === true) {
|
|
return _curry1(function (b) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else if (n === 3 && c != null && c['@@functional/placeholder'] === true) {
|
|
return _curry1(function (c) {
|
|
return fn(a, b, c);
|
|
});
|
|
} else {
|
|
return fn(a, b, c);
|
|
}
|
|
};
|
|
};
|
|
|
|
var _dissoc = function _dissoc(prop, obj) {
|
|
var result = {};
|
|
for (var p in obj) {
|
|
if (p !== prop) {
|
|
result[p] = obj[p];
|
|
}
|
|
}
|
|
return result;
|
|
};
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Polyfill
|
|
// SameValue algorithm
|
|
// Steps 1-5, 7-10
|
|
// Steps 6.b-6.e: +0 != -0
|
|
// Step 6.a: NaN == NaN
|
|
var _eq = function _eq(x, y) {
|
|
// SameValue algorithm
|
|
if (x === y) {
|
|
// Steps 1-5, 7-10
|
|
// Steps 6.b-6.e: +0 != -0
|
|
return x !== 0 || 1 / x === 1 / y;
|
|
} else {
|
|
// Step 6.a: NaN == NaN
|
|
return x !== x && y !== y;
|
|
}
|
|
};
|
|
|
|
var _filter = function _filter(fn, list) {
|
|
var idx = 0, len = list.length, result = [];
|
|
while (idx < len) {
|
|
if (fn(list[idx])) {
|
|
result[result.length] = list[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
var _filterIndexed = function _filterIndexed(fn, list) {
|
|
var idx = 0, len = list.length, result = [];
|
|
while (idx < len) {
|
|
if (fn(list[idx], idx, list)) {
|
|
result[result.length] = list[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
// i can't bear not to return *something*
|
|
var _forEach = function _forEach(fn, list) {
|
|
var idx = 0, len = list.length;
|
|
while (idx < len) {
|
|
fn(list[idx]);
|
|
idx += 1;
|
|
}
|
|
// i can't bear not to return *something*
|
|
return list;
|
|
};
|
|
|
|
var _forceReduced = function _forceReduced(x) {
|
|
return {
|
|
'@@transducer/value': x,
|
|
'@@transducer/reduced': true
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
* @param {Function} fn The strategy for extracting function names from an object
|
|
* @return {Function} A function that takes an object and returns an array of function names.
|
|
*/
|
|
var _functionsWith = function _functionsWith(fn) {
|
|
return function (obj) {
|
|
return _filter(function (key) {
|
|
return typeof obj[key] === 'function';
|
|
}, fn(obj));
|
|
};
|
|
};
|
|
|
|
var _gt = function _gt(a, b) {
|
|
return a > b;
|
|
};
|
|
|
|
var _has = function _has(prop, obj) {
|
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
};
|
|
|
|
var _identity = function _identity(x) {
|
|
return x;
|
|
};
|
|
|
|
/**
|
|
* Tests whether or not an object is an array.
|
|
*
|
|
* @private
|
|
* @param {*} val The object to test.
|
|
* @return {Boolean} `true` if `val` is an array, `false` otherwise.
|
|
* @example
|
|
*
|
|
* _isArray([]); //=> true
|
|
* _isArray(null); //=> false
|
|
* _isArray({}); //=> false
|
|
*/
|
|
var _isArray = Array.isArray || function _isArray(val) {
|
|
return val != null && val.length >= 0 && Object.prototype.toString.call(val) === '[object Array]';
|
|
};
|
|
|
|
/**
|
|
* Determine if the passed argument is an integer.
|
|
*
|
|
* @private
|
|
* @param {*} n
|
|
* @category Type
|
|
* @return {Boolean}
|
|
*/
|
|
var _isInteger = Number.isInteger || function _isInteger(n) {
|
|
return n << 0 === n;
|
|
};
|
|
|
|
/**
|
|
* Tests if a value is a thenable (promise).
|
|
*/
|
|
var _isThenable = function _isThenable(value) {
|
|
return value != null && value === Object(value) && typeof value.then === 'function';
|
|
};
|
|
|
|
var _isTransformer = function _isTransformer(obj) {
|
|
return typeof obj['@@transducer/step'] === 'function';
|
|
};
|
|
|
|
var _lt = function _lt(a, b) {
|
|
return a < b;
|
|
};
|
|
|
|
var _map = function _map(fn, list) {
|
|
var idx = 0, len = list.length, result = [];
|
|
while (idx < len) {
|
|
result[idx] = fn(list[idx]);
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
};
|
|
|
|
var _multiply = function _multiply(a, b) {
|
|
return a * b;
|
|
};
|
|
|
|
var _nth = function _nth(n, list) {
|
|
return n < 0 ? list[list.length + n] : list[n];
|
|
};
|
|
|
|
/**
|
|
* internal path function
|
|
* Takes an array, paths, indicating the deep set of keys
|
|
* to find.
|
|
*
|
|
* @private
|
|
* @memberOf R
|
|
* @category Object
|
|
* @param {Array} paths An array of strings to map to object properties
|
|
* @param {Object} obj The object to find the path in
|
|
* @return {Array} The value at the end of the path or `undefined`.
|
|
* @example
|
|
*
|
|
* _path(['a', 'b'], {a: {b: 2}}); //=> 2
|
|
*/
|
|
var _path = function _path(paths, obj) {
|
|
if (obj == null) {
|
|
return;
|
|
} else {
|
|
var val = obj;
|
|
for (var idx = 0, len = paths.length; idx < len && val != null; idx += 1) {
|
|
val = val[paths[idx]];
|
|
}
|
|
return val;
|
|
}
|
|
};
|
|
|
|
var _prepend = function _prepend(el, list) {
|
|
return _concat([el], list);
|
|
};
|
|
|
|
var _quote = function _quote(s) {
|
|
return '"' + s.replace(/"/g, '\\"') + '"';
|
|
};
|
|
|
|
var _reduced = function _reduced(x) {
|
|
return x && x['@@transducer/reduced'] ? x : {
|
|
'@@transducer/value': x,
|
|
'@@transducer/reduced': true
|
|
};
|
|
};
|
|
|
|
/**
|
|
* An optimized, private array `slice` implementation.
|
|
*
|
|
* @private
|
|
* @param {Arguments|Array} args The array or arguments object to consider.
|
|
* @param {Number} [from=0] The array index to slice from, inclusive.
|
|
* @param {Number} [to=args.length] The array index to slice to, exclusive.
|
|
* @return {Array} A new, sliced array.
|
|
* @example
|
|
*
|
|
* _slice([1, 2, 3, 4, 5], 1, 3); //=> [2, 3]
|
|
*
|
|
* var firstThreeArgs = function(a, b, c, d) {
|
|
* return _slice(arguments, 0, 3);
|
|
* };
|
|
* firstThreeArgs(1, 2, 3, 4); //=> [1, 2, 3]
|
|
*/
|
|
var _slice = function _slice(args, from, to) {
|
|
switch (arguments.length) {
|
|
case 1:
|
|
return _slice(args, 0, args.length);
|
|
case 2:
|
|
return _slice(args, from, args.length);
|
|
default:
|
|
var list = [];
|
|
var idx = 0;
|
|
var len = Math.max(0, Math.min(args.length, to) - from);
|
|
while (idx < len) {
|
|
list[idx] = args[from + idx];
|
|
idx += 1;
|
|
}
|
|
return list;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Polyfill from <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString>.
|
|
*/
|
|
var _toISOString = function () {
|
|
var pad = function pad(n) {
|
|
return (n < 10 ? '0' : '') + n;
|
|
};
|
|
return typeof Date.prototype.toISOString === 'function' ? function _toISOString(d) {
|
|
return d.toISOString();
|
|
} : function _toISOString(d) {
|
|
return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + '.' + (d.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) + 'Z';
|
|
};
|
|
}();
|
|
|
|
var _xdropRepeatsWith = function () {
|
|
function XDropRepeatsWith(pred, xf) {
|
|
this.xf = xf;
|
|
this.pred = pred;
|
|
this.lastValue = undefined;
|
|
this.seenFirstValue = false;
|
|
}
|
|
XDropRepeatsWith.prototype['@@transducer/init'] = function () {
|
|
return this.xf['@@transducer/init']();
|
|
};
|
|
XDropRepeatsWith.prototype['@@transducer/result'] = function (result) {
|
|
return this.xf['@@transducer/result'](result);
|
|
};
|
|
XDropRepeatsWith.prototype['@@transducer/step'] = function (result, input) {
|
|
var sameAsLast = false;
|
|
if (!this.seenFirstValue) {
|
|
this.seenFirstValue = true;
|
|
} else if (this.pred(this.lastValue, input)) {
|
|
sameAsLast = true;
|
|
}
|
|
this.lastValue = input;
|
|
return sameAsLast ? result : this.xf['@@transducer/step'](result, input);
|
|
};
|
|
return _curry2(function _xdropRepeatsWith(pred, xf) {
|
|
return new XDropRepeatsWith(pred, xf);
|
|
});
|
|
}();
|
|
|
|
var _xfBase = {
|
|
init: function () {
|
|
return this.xf['@@transducer/init']();
|
|
},
|
|
result: function (result) {
|
|
return this.xf['@@transducer/result'](result);
|
|
}
|
|
};
|
|
|
|
var _xfilter = function () {
|
|
function XFilter(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
}
|
|
XFilter.prototype['@@transducer/init'] = _xfBase.init;
|
|
XFilter.prototype['@@transducer/result'] = _xfBase.result;
|
|
XFilter.prototype['@@transducer/step'] = function (result, input) {
|
|
return this.f(input) ? this.xf['@@transducer/step'](result, input) : result;
|
|
};
|
|
return _curry2(function _xfilter(f, xf) {
|
|
return new XFilter(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xfind = function () {
|
|
function XFind(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
this.found = false;
|
|
}
|
|
XFind.prototype['@@transducer/init'] = _xfBase.init;
|
|
XFind.prototype['@@transducer/result'] = function (result) {
|
|
if (!this.found) {
|
|
result = this.xf['@@transducer/step'](result, void 0);
|
|
}
|
|
return this.xf['@@transducer/result'](result);
|
|
};
|
|
XFind.prototype['@@transducer/step'] = function (result, input) {
|
|
if (this.f(input)) {
|
|
this.found = true;
|
|
result = _reduced(this.xf['@@transducer/step'](result, input));
|
|
}
|
|
return result;
|
|
};
|
|
return _curry2(function _xfind(f, xf) {
|
|
return new XFind(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xfindIndex = function () {
|
|
function XFindIndex(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
this.idx = -1;
|
|
this.found = false;
|
|
}
|
|
XFindIndex.prototype['@@transducer/init'] = _xfBase.init;
|
|
XFindIndex.prototype['@@transducer/result'] = function (result) {
|
|
if (!this.found) {
|
|
result = this.xf['@@transducer/step'](result, -1);
|
|
}
|
|
return this.xf['@@transducer/result'](result);
|
|
};
|
|
XFindIndex.prototype['@@transducer/step'] = function (result, input) {
|
|
this.idx += 1;
|
|
if (this.f(input)) {
|
|
this.found = true;
|
|
result = _reduced(this.xf['@@transducer/step'](result, this.idx));
|
|
}
|
|
return result;
|
|
};
|
|
return _curry2(function _xfindIndex(f, xf) {
|
|
return new XFindIndex(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xfindLast = function () {
|
|
function XFindLast(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
}
|
|
XFindLast.prototype['@@transducer/init'] = _xfBase.init;
|
|
XFindLast.prototype['@@transducer/result'] = function (result) {
|
|
return this.xf['@@transducer/result'](this.xf['@@transducer/step'](result, this.last));
|
|
};
|
|
XFindLast.prototype['@@transducer/step'] = function (result, input) {
|
|
if (this.f(input)) {
|
|
this.last = input;
|
|
}
|
|
return result;
|
|
};
|
|
return _curry2(function _xfindLast(f, xf) {
|
|
return new XFindLast(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xfindLastIndex = function () {
|
|
function XFindLastIndex(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
this.idx = -1;
|
|
this.lastIdx = -1;
|
|
}
|
|
XFindLastIndex.prototype['@@transducer/init'] = _xfBase.init;
|
|
XFindLastIndex.prototype['@@transducer/result'] = function (result) {
|
|
return this.xf['@@transducer/result'](this.xf['@@transducer/step'](result, this.lastIdx));
|
|
};
|
|
XFindLastIndex.prototype['@@transducer/step'] = function (result, input) {
|
|
this.idx += 1;
|
|
if (this.f(input)) {
|
|
this.lastIdx = this.idx;
|
|
}
|
|
return result;
|
|
};
|
|
return _curry2(function _xfindLastIndex(f, xf) {
|
|
return new XFindLastIndex(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xmap = function () {
|
|
function XMap(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
}
|
|
XMap.prototype['@@transducer/init'] = _xfBase.init;
|
|
XMap.prototype['@@transducer/result'] = _xfBase.result;
|
|
XMap.prototype['@@transducer/step'] = function (result, input) {
|
|
return this.xf['@@transducer/step'](result, this.f(input));
|
|
};
|
|
return _curry2(function _xmap(f, xf) {
|
|
return new XMap(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xtake = function () {
|
|
function XTake(n, xf) {
|
|
this.xf = xf;
|
|
this.n = n;
|
|
}
|
|
XTake.prototype['@@transducer/init'] = _xfBase.init;
|
|
XTake.prototype['@@transducer/result'] = _xfBase.result;
|
|
XTake.prototype['@@transducer/step'] = function (result, input) {
|
|
this.n -= 1;
|
|
return this.n === 0 ? _reduced(this.xf['@@transducer/step'](result, input)) : this.xf['@@transducer/step'](result, input);
|
|
};
|
|
return _curry2(function _xtake(n, xf) {
|
|
return new XTake(n, xf);
|
|
});
|
|
}();
|
|
|
|
var _xtakeWhile = function () {
|
|
function XTakeWhile(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
}
|
|
XTakeWhile.prototype['@@transducer/init'] = _xfBase.init;
|
|
XTakeWhile.prototype['@@transducer/result'] = _xfBase.result;
|
|
XTakeWhile.prototype['@@transducer/step'] = function (result, input) {
|
|
return this.f(input) ? this.xf['@@transducer/step'](result, input) : _reduced(result);
|
|
};
|
|
return _curry2(function _xtakeWhile(f, xf) {
|
|
return new XTakeWhile(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xwrap = function () {
|
|
function XWrap(fn) {
|
|
this.f = fn;
|
|
}
|
|
XWrap.prototype['@@transducer/init'] = function () {
|
|
throw new Error('init not implemented on XWrap');
|
|
};
|
|
XWrap.prototype['@@transducer/result'] = function (acc) {
|
|
return acc;
|
|
};
|
|
XWrap.prototype['@@transducer/step'] = function (acc, x) {
|
|
return this.f(acc, x);
|
|
};
|
|
return function _xwrap(fn) {
|
|
return new XWrap(fn);
|
|
};
|
|
}();
|
|
|
|
/**
|
|
* Adds two numbers (or strings). Equivalent to `a + b` but curried.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Number
|
|
* @sig String -> String -> String
|
|
* @param {Number|String} a The first value.
|
|
* @param {Number|String} b The second value.
|
|
* @return {Number|String} The result of `a + b`.
|
|
* @example
|
|
*
|
|
* R.add(2, 3); //=> 5
|
|
* R.add(7)(10); //=> 17
|
|
*/
|
|
var add = _curry2(_add);
|
|
|
|
/**
|
|
* Applies a function to the value at the given index of an array,
|
|
* returning a new copy of the array with the element at the given
|
|
* index replaced with the result of the function application.
|
|
* @see R.update
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> a) -> Number -> [a] -> [a]
|
|
* @param {Function} fn The function to apply.
|
|
* @param {Number} idx The index.
|
|
* @param {Array|Arguments} list An array-like object whose value
|
|
* at the supplied index will be replaced.
|
|
* @return {Array} A copy of the supplied array-like object with
|
|
* the element at index `idx` replaced with the value
|
|
* returned by applying `fn` to the existing element.
|
|
* @example
|
|
*
|
|
* R.adjust(R.add(10), 1, [0, 1, 2]); //=> [0, 11, 2]
|
|
* R.adjust(R.add(10))(1)([0, 1, 2]); //=> [0, 11, 2]
|
|
*/
|
|
var adjust = _curry3(function (fn, idx, list) {
|
|
if (idx >= list.length || idx < -list.length) {
|
|
return list;
|
|
}
|
|
var start = idx < 0 ? list.length : 0;
|
|
var _idx = start + idx;
|
|
var _list = _concat(list);
|
|
_list[_idx] = fn(list[_idx]);
|
|
return _list;
|
|
});
|
|
|
|
/**
|
|
* Returns a function that always returns the given value. Note that for non-primitives the value
|
|
* returned is a reference to the original value.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig a -> (* -> a)
|
|
* @param {*} val The value to wrap in a function
|
|
* @return {Function} A Function :: * -> val.
|
|
* @example
|
|
*
|
|
* var t = R.always('Tee');
|
|
* t(); //=> 'Tee'
|
|
*/
|
|
var always = _curry1(function always(val) {
|
|
return function () {
|
|
return val;
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Returns a new list, composed of n-tuples of consecutive elements
|
|
* If `n` is greater than the length of the list, an empty list is returned.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> [a] -> [[a]]
|
|
* @param {Number} n The size of the tuples to create
|
|
* @param {Array} list The list to split into `n`-tuples
|
|
* @return {Array} The new list.
|
|
* @example
|
|
*
|
|
* R.aperture(2, [1, 2, 3, 4, 5]); //=> [[1, 2], [2, 3], [3, 4], [4, 5]]
|
|
* R.aperture(3, [1, 2, 3, 4, 5]); //=> [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
|
|
* R.aperture(7, [1, 2, 3, 4, 5]); //=> []
|
|
*/
|
|
var aperture = _curry2(function aperture(n, list) {
|
|
var idx = 0;
|
|
var limit = list.length - (n - 1);
|
|
var acc = new Array(limit >= 0 ? limit : 0);
|
|
while (idx < limit) {
|
|
acc[idx] = _slice(list, idx, idx + n);
|
|
idx += 1;
|
|
}
|
|
return acc;
|
|
});
|
|
|
|
/**
|
|
* Applies function `fn` to the argument list `args`. This is useful for
|
|
* creating a fixed-arity function from a variadic function. `fn` should
|
|
* be a bound function if context is significant.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (*... -> a) -> [*] -> a
|
|
* @param {Function} fn
|
|
* @param {Array} args
|
|
* @return {*}
|
|
* @example
|
|
*
|
|
* var nums = [1, 2, 3, -99, 42, 6, 7];
|
|
* R.apply(Math.max, nums); //=> 42
|
|
*/
|
|
var apply = _curry2(function apply(fn, args) {
|
|
return fn.apply(this, args);
|
|
});
|
|
|
|
/**
|
|
* Wraps a function of any arity (including nullary) in a function that accepts exactly `n`
|
|
* parameters. Unlike `nAry`, which passes only `n` arguments to the wrapped function,
|
|
* functions produced by `arity` will pass all provided arguments to the wrapped function.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @sig (Number, (* -> *)) -> (* -> *)
|
|
* @category Function
|
|
* @param {Number} n The desired arity of the returned function.
|
|
* @param {Function} fn The function to wrap.
|
|
* @return {Function} A new function wrapping `fn`. The new function is
|
|
* guaranteed to be of arity `n`.
|
|
* @deprecated since v0.15.0
|
|
* @example
|
|
*
|
|
* var takesTwoArgs = function(a, b) {
|
|
* return [a, b];
|
|
* };
|
|
* takesTwoArgs.length; //=> 2
|
|
* takesTwoArgs(1, 2); //=> [1, 2]
|
|
*
|
|
* var takesOneArg = R.arity(1, takesTwoArgs);
|
|
* takesOneArg.length; //=> 1
|
|
* // All arguments are passed through to the wrapped function
|
|
* takesOneArg(1, 2); //=> [1, 2]
|
|
*/
|
|
// jshint unused:vars
|
|
var arity = _curry2(function (n, fn) {
|
|
// jshint unused:vars
|
|
switch (n) {
|
|
case 0:
|
|
return function () {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 1:
|
|
return function (a0) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 2:
|
|
return function (a0, a1) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 3:
|
|
return function (a0, a1, a2) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 4:
|
|
return function (a0, a1, a2, a3) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 5:
|
|
return function (a0, a1, a2, a3, a4) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 6:
|
|
return function (a0, a1, a2, a3, a4, a5) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 7:
|
|
return function (a0, a1, a2, a3, a4, a5, a6) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 8:
|
|
return function (a0, a1, a2, a3, a4, a5, a6, a7) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 9:
|
|
return function (a0, a1, a2, a3, a4, a5, a6, a7, a8) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
case 10:
|
|
return function (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
|
return fn.apply(this, arguments);
|
|
};
|
|
default:
|
|
throw new Error('First argument to arity must be a non-negative integer no greater than ten');
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Makes a shallow clone of an object, setting or overriding the specified
|
|
* property with the given value. Note that this copies and flattens
|
|
* prototype properties onto the new object as well. All non-primitive
|
|
* properties are copied by reference.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig String -> a -> {k: v} -> {k: v}
|
|
* @param {String} prop the property name to set
|
|
* @param {*} val the new value
|
|
* @param {Object} obj the object to clone
|
|
* @return {Object} a new object similar to the original except for the specified property.
|
|
* @example
|
|
*
|
|
* R.assoc('c', 3, {a: 1, b: 2}); //=> {a: 1, b: 2, c: 3}
|
|
*/
|
|
var assoc = _curry3(_assoc);
|
|
|
|
/**
|
|
* Creates a function that is bound to a context.
|
|
* Note: `R.bind` does not provide the additional argument-binding capabilities of
|
|
* [Function.prototype.bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @category Object
|
|
* @see R.partial
|
|
* @sig (* -> *) -> {*} -> (* -> *)
|
|
* @param {Function} fn The function to bind to context
|
|
* @param {Object} thisObj The context to bind `fn` to
|
|
* @return {Function} A function that will execute in the context of `thisObj`.
|
|
*/
|
|
var bind = _curry2(function bind(fn, thisObj) {
|
|
return arity(fn.length, function () {
|
|
return fn.apply(thisObj, arguments);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* A function wrapping calls to the two functions in an `&&` operation, returning the result of the first
|
|
* function if it is false-y and the result of the second function otherwise. Note that this is
|
|
* short-circuited, meaning that the second function will not be invoked if the first returns a false-y
|
|
* value.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean)
|
|
* @param {Function} f a predicate
|
|
* @param {Function} g another predicate
|
|
* @return {Function} a function that applies its arguments to `f` and `g` and `&&`s their outputs together.
|
|
* @example
|
|
*
|
|
* var gt10 = function(x) { return x > 10; };
|
|
* var even = function(x) { return x % 2 === 0 };
|
|
* var f = R.both(gt10, even);
|
|
* f(100); //=> true
|
|
* f(101); //=> false
|
|
*/
|
|
var both = _curry2(function both(f, g) {
|
|
return function _both() {
|
|
return f.apply(this, arguments) && g.apply(this, arguments);
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Makes a comparator function out of a function that reports whether the first element is less than the second.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (a, b -> Boolean) -> (a, b -> Number)
|
|
* @param {Function} pred A predicate function of arity two.
|
|
* @return {Function} A Function :: a -> b -> Int that returns `-1` if a < b, `1` if b < a, otherwise `0`.
|
|
* @example
|
|
*
|
|
* var cmp = R.comparator(function(a, b) {
|
|
* return a.age < b.age;
|
|
* });
|
|
* var people = [
|
|
* // ...
|
|
* ];
|
|
* R.sort(cmp, people);
|
|
*/
|
|
var comparator = _curry1(function comparator(pred) {
|
|
return function (a, b) {
|
|
return pred(a, b) ? -1 : pred(b, a) ? 1 : 0;
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Takes a function `f` and returns a function `g` such that:
|
|
*
|
|
* - applying `g` to zero or more arguments will give __true__ if applying
|
|
* the same arguments to `f` gives a logical __false__ value; and
|
|
*
|
|
* - applying `g` to zero or more arguments will give __false__ if applying
|
|
* the same arguments to `f` gives a logical __true__ value.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig (*... -> *) -> (*... -> Boolean)
|
|
* @param {Function} f
|
|
* @return {Function}
|
|
* @example
|
|
*
|
|
* var isEven = function(n) { return n % 2 === 0; };
|
|
* var isOdd = R.complement(isEven);
|
|
* isOdd(21); //=> true
|
|
* isOdd(42); //=> false
|
|
*/
|
|
var complement = _curry1(_complement);
|
|
|
|
/**
|
|
* Returns a function, `fn`, which encapsulates if/else-if/else logic.
|
|
* Each argument to `R.cond` is a [predicate, transform] pair. All of
|
|
* the arguments to `fn` are applied to each of the predicates in turn
|
|
* until one returns a "truthy" value, at which point `fn` returns the
|
|
* result of applying its arguments to the corresponding transformer.
|
|
* If none of the predicates matches, `fn` returns undefined.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig [(*... -> Boolean),(*... -> *)]... -> (*... -> *)
|
|
* @param {...Function} functions
|
|
* @return {Function}
|
|
* @example
|
|
*
|
|
* var fn = R.cond(
|
|
* [R.equals(0), R.always('water freezes at 0°C')],
|
|
* [R.equals(100), R.always('water boils at 100°C')],
|
|
* [R.T, function(temp) { return 'nothing special happens at ' + temp + '°C'; }]
|
|
* );
|
|
* fn(0); //=> 'water freezes at 0°C'
|
|
* fn(50); //=> 'nothing special happens at 50°C'
|
|
* fn(100); //=> 'water boils at 100°C'
|
|
*/
|
|
var cond = function cond() {
|
|
var pairs = arguments;
|
|
return function () {
|
|
var idx = 0;
|
|
while (idx < pairs.length) {
|
|
if (pairs[idx][0].apply(this, arguments)) {
|
|
return pairs[idx][1].apply(this, arguments);
|
|
}
|
|
idx += 1;
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Returns `true` if the `x` is found in the `list`, using `pred` as an
|
|
* equality predicate for `x`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a, a -> Boolean) -> a -> [a] -> Boolean
|
|
* @param {Function} pred A predicate used to test whether two items are equal.
|
|
* @param {*} x The item to find
|
|
* @param {Array} list The list to iterate over
|
|
* @return {Boolean} `true` if `x` is in `list`, else `false`.
|
|
* @example
|
|
*
|
|
* var xs = [{x: 12}, {x: 11}, {x: 10}];
|
|
* R.containsWith(function(a, b) { return a.x === b.x; }, {x: 10}, xs); //=> true
|
|
* R.containsWith(function(a, b) { return a.x === b.x; }, {x: 1}, xs); //=> false
|
|
*/
|
|
var containsWith = _curry3(_containsWith);
|
|
|
|
/**
|
|
* Counts the elements of a list according to how many match each value
|
|
* of a key generated by the supplied function. Returns an object
|
|
* mapping the keys produced by `fn` to the number of occurrences in
|
|
* the list. Note that all keys are coerced to strings because of how
|
|
* JavaScript objects work.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig (a -> String) -> [a] -> {*}
|
|
* @param {Function} fn The function used to map values to keys.
|
|
* @param {Array} list The list to count elements from.
|
|
* @return {Object} An object mapping keys to number of occurrences in the list.
|
|
* @example
|
|
*
|
|
* var numbers = [1.0, 1.1, 1.2, 2.0, 3.0, 2.2];
|
|
* var letters = R.split('', 'abcABCaaaBBc');
|
|
* R.countBy(Math.floor)(numbers); //=> {'1': 3, '2': 2, '3': 1}
|
|
* R.countBy(R.toLower)(letters); //=> {'a': 5, 'b': 4, 'c': 3}
|
|
*/
|
|
var countBy = _curry2(function countBy(fn, list) {
|
|
var counts = {};
|
|
var len = list.length;
|
|
var idx = 0;
|
|
while (idx < len) {
|
|
var key = fn(list[idx]);
|
|
counts[key] = (_has(key, counts) ? counts[key] : 0) + 1;
|
|
idx += 1;
|
|
}
|
|
return counts;
|
|
});
|
|
|
|
/**
|
|
* Creates an object containing a single key:value pair.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig String -> a -> {String:a}
|
|
* @param {String} key
|
|
* @param {*} val
|
|
* @return {Object}
|
|
* @example
|
|
*
|
|
* var matchPhrases = R.compose(
|
|
* R.createMapEntry('must'),
|
|
* R.map(R.createMapEntry('match_phrase'))
|
|
* );
|
|
* matchPhrases(['foo', 'bar', 'baz']); //=> {must: [{match_phrase: 'foo'}, {match_phrase: 'bar'}, {match_phrase: 'baz'}]}
|
|
*/
|
|
var createMapEntry = _curry2(_createMapEntry);
|
|
|
|
/**
|
|
* Decrements its argument.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number
|
|
* @param {Number} n
|
|
* @return {Number}
|
|
* @example
|
|
*
|
|
* R.dec(42); //=> 41
|
|
*/
|
|
var dec = add(-1);
|
|
|
|
/**
|
|
* Returns the second argument if it is not null or undefined. If it is null
|
|
* or undefined, the first (default) argument is returned.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig a -> b -> a | b
|
|
* @param {a} val The default value.
|
|
* @param {b} val The value to return if it is not null or undefined
|
|
* @return {*} The the second value or the default value
|
|
* @example
|
|
*
|
|
* var defaultTo42 = defaultTo(42);
|
|
*
|
|
* defaultTo42(null); //=> 42
|
|
* defaultTo42(undefined); //=> 42
|
|
* defaultTo42('Ramda'); //=> 'Ramda'
|
|
*/
|
|
var defaultTo = _curry2(function defaultTo(d, v) {
|
|
return v == null ? d : v;
|
|
});
|
|
|
|
/**
|
|
* Finds the set (i.e. no duplicates) of all elements in the first list not contained in the second list.
|
|
* Duplication is determined according to the value returned by applying the supplied predicate to two list
|
|
* elements.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig (a,a -> Boolean) -> [a] -> [a] -> [a]
|
|
* @param {Function} pred A predicate used to test whether two items are equal.
|
|
* @param {Array} list1 The first list.
|
|
* @param {Array} list2 The second list.
|
|
* @see R.difference
|
|
* @return {Array} The elements in `list1` that are not in `list2`.
|
|
* @example
|
|
*
|
|
* function cmp(x, y) { return x.a === y.a; }
|
|
* var l1 = [{a: 1}, {a: 2}, {a: 3}];
|
|
* var l2 = [{a: 3}, {a: 4}];
|
|
* R.differenceWith(cmp, l1, l2); //=> [{a: 1}, {a: 2}]
|
|
*/
|
|
var differenceWith = _curry3(function differenceWith(pred, first, second) {
|
|
var out = [];
|
|
var idx = 0;
|
|
var firstLen = first.length;
|
|
var containsPred = containsWith(pred);
|
|
while (idx < firstLen) {
|
|
if (!containsPred(first[idx], second) && !containsPred(first[idx], out)) {
|
|
out[out.length] = first[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
return out;
|
|
});
|
|
|
|
/**
|
|
* Returns a new object that does not contain a `prop` property.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig String -> {k: v} -> {k: v}
|
|
* @param {String} prop the name of the property to dissociate
|
|
* @param {Object} obj the object to clone
|
|
* @return {Object} a new object similar to the original but without the specified property
|
|
* @example
|
|
*
|
|
* R.dissoc('b', {a: 1, b: 2, c: 3}); //=> {a: 1, c: 3}
|
|
*/
|
|
var dissoc = _curry2(_dissoc);
|
|
|
|
/**
|
|
* Divides two numbers. Equivalent to `a / b`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Number
|
|
* @param {Number} a The first value.
|
|
* @param {Number} b The second value.
|
|
* @return {Number} The result of `a / b`.
|
|
* @example
|
|
*
|
|
* R.divide(71, 100); //=> 0.71
|
|
*
|
|
* var half = R.divide(R.__, 2);
|
|
* half(42); //=> 21
|
|
*
|
|
* var reciprocal = R.divide(1);
|
|
* reciprocal(4); //=> 0.25
|
|
*/
|
|
var divide = _curry2(function divide(a, b) {
|
|
return a / b;
|
|
});
|
|
|
|
/**
|
|
* A function wrapping calls to the two functions in an `||` operation, returning the result of the first
|
|
* function if it is truth-y and the result of the second function otherwise. Note that this is
|
|
* short-circuited, meaning that the second function will not be invoked if the first returns a truth-y
|
|
* value.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig (*... -> Boolean) -> (*... -> Boolean) -> (*... -> Boolean)
|
|
* @param {Function} f a predicate
|
|
* @param {Function} g another predicate
|
|
* @return {Function} a function that applies its arguments to `f` and `g` and `||`s their outputs together.
|
|
* @example
|
|
*
|
|
* var gt10 = function(x) { return x > 10; };
|
|
* var even = function(x) { return x % 2 === 0 };
|
|
* var f = R.either(gt10, even);
|
|
* f(101); //=> true
|
|
* f(8); //=> true
|
|
*/
|
|
var either = _curry2(function either(f, g) {
|
|
return function _either() {
|
|
return f.apply(this, arguments) || g.apply(this, arguments);
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Tests if two items are equal. Equality is strict here, meaning reference equality for objects and
|
|
* non-coercing equality for primitives.
|
|
*
|
|
* Has `Object.is` semantics: `NaN` is considered equal to `NaN`; `0` and `-0`
|
|
* are not considered equal.
|
|
* @see R.identical
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig a -> a -> Boolean
|
|
* @param {*} a
|
|
* @param {*} b
|
|
* @return {Boolean}
|
|
* @deprecated since v0.15.0
|
|
* @example
|
|
*
|
|
* var o = {};
|
|
* R.eq(o, o); //=> true
|
|
* R.eq(o, {}); //=> false
|
|
* R.eq(1, 1); //=> true
|
|
* R.eq(1, '1'); //=> false
|
|
* R.eq(0, -0); //=> false
|
|
* R.eq(NaN, NaN); //=> true
|
|
*/
|
|
var eq = _curry2(_eq);
|
|
|
|
/**
|
|
* Creates a new object by recursively evolving a shallow copy of `object`, according to the
|
|
* `transformation` functions. All non-primitive properties are copied by reference.
|
|
*
|
|
* A `tranformation` function will not be invoked if its corresponding key does not exist in
|
|
* the evolved object.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {k: (v -> v)} -> {k: v} -> {k: v}
|
|
* @param {Object} transformations The object specifying transformation functions to apply
|
|
* to the object.
|
|
* @param {Object} object The object to be transformed.
|
|
* @return {Object} The transformed object.
|
|
* @example
|
|
*
|
|
* var tomato = {firstName: ' Tomato ', elapsed: 100, remaining: 1400};
|
|
* var transformations = {
|
|
* firstName: R.trim,
|
|
* lastName: R.trim, // Will not get invoked.
|
|
* data: {elapsed: R.add(1), remaining: R.add(-1)}
|
|
* };
|
|
* R.evolve(transformations, tomato); //=> {firstName: 'Tomato', data: {elapsed: 101, remaining: 1399}}
|
|
*/
|
|
var evolve = _curry2(function evolve(transformations, object) {
|
|
var transformation, key, type, result = {};
|
|
for (key in object) {
|
|
transformation = transformations[key];
|
|
type = typeof transformation;
|
|
result[key] = type === 'function' ? transformation(object[key]) : type === 'object' ? evolve(transformations[key], object[key]) : object[key];
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Like `filter`, but passes additional parameters to the predicate function. The predicate
|
|
* function is passed three arguments: *(value, index, list)*.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a, i, [a] -> Boolean) -> [a] -> [a]
|
|
* @param {Function} fn The function called per iteration.
|
|
* @param {Array} list The collection to iterate over.
|
|
* @return {Array} The new filtered array.
|
|
* @deprecated since v0.15.0
|
|
* @see R.addIndex
|
|
* @example
|
|
*
|
|
* var lastTwo = function(val, idx, list) {
|
|
* return list.length - idx <= 2;
|
|
* };
|
|
* R.filterIndexed(lastTwo, [8, 6, 7, 5, 3, 0, 9]); //=> [0, 9]
|
|
*/
|
|
var filterIndexed = _curry2(_filterIndexed);
|
|
|
|
/**
|
|
* Like `forEach`, but but passes additional parameters to the predicate function.
|
|
*
|
|
* `fn` receives three arguments: *(value, index, list)*.
|
|
*
|
|
* Note: `R.forEachIndexed` does not skip deleted or unassigned indices (sparse arrays),
|
|
* unlike the native `Array.prototype.forEach` method. For more details on this behavior,
|
|
* see:
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Description
|
|
*
|
|
* Also note that, unlike `Array.prototype.forEach`, Ramda's `forEach` returns the original
|
|
* array. In some libraries this function is named `each`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a, i, [a] -> ) -> [a] -> [a]
|
|
* @param {Function} fn The function to invoke. Receives three arguments:
|
|
* (`value`, `index`, `list`).
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {Array} The original list.
|
|
* @deprecated since v0.15.0
|
|
* @see R.addIndex
|
|
* @example
|
|
*
|
|
* // Note that having access to the original `list` allows for
|
|
* // mutation. While you *can* do this, it's very un-functional behavior:
|
|
* var plusFive = function(num, idx, list) { list[idx] = num + 5 };
|
|
* R.forEachIndexed(plusFive, [1, 2, 3]); //=> [6, 7, 8]
|
|
*/
|
|
// i can't bear not to return *something*
|
|
var forEachIndexed = _curry2(function forEachIndexed(fn, list) {
|
|
var idx = 0, len = list.length;
|
|
while (idx < len) {
|
|
fn(list[idx], idx, list);
|
|
idx += 1;
|
|
}
|
|
// i can't bear not to return *something*
|
|
return list;
|
|
});
|
|
|
|
/**
|
|
* Creates a new object out of a list key-value pairs.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [[k,v]] -> {k: v}
|
|
* @param {Array} pairs An array of two-element arrays that will be the keys and values of the output object.
|
|
* @return {Object} The object made by pairing up `keys` and `values`.
|
|
* @example
|
|
*
|
|
* R.fromPairs([['a', 1], ['b', 2], ['c', 3]]); //=> {a: 1, b: 2, c: 3}
|
|
*/
|
|
var fromPairs = _curry1(function fromPairs(pairs) {
|
|
var idx = 0, len = pairs.length, out = {};
|
|
while (idx < len) {
|
|
if (_isArray(pairs[idx]) && pairs[idx].length) {
|
|
out[pairs[idx][0]] = pairs[idx][1];
|
|
}
|
|
idx += 1;
|
|
}
|
|
return out;
|
|
});
|
|
|
|
/**
|
|
* Returns true if the first parameter is greater than the second.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Boolean
|
|
* @param {Number} a
|
|
* @param {Number} b
|
|
* @return {Boolean} a > b
|
|
* @example
|
|
*
|
|
* R.gt(2, 6); //=> false
|
|
* R.gt(2, 0); //=> true
|
|
* R.gt(2, 2); //=> false
|
|
* R.gt(R.__, 2)(10); //=> true
|
|
* R.gt(2)(10); //=> false
|
|
*/
|
|
var gt = _curry2(_gt);
|
|
|
|
/**
|
|
* Returns true if the first parameter is greater than or equal to the second.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Boolean
|
|
* @param {Number} a
|
|
* @param {Number} b
|
|
* @return {Boolean} a >= b
|
|
* @example
|
|
*
|
|
* R.gte(2, 6); //=> false
|
|
* R.gte(2, 0); //=> true
|
|
* R.gte(2, 2); //=> true
|
|
* R.gte(R.__, 6)(2); //=> false
|
|
* R.gte(2)(0); //=> true
|
|
*/
|
|
var gte = _curry2(function gte(a, b) {
|
|
return a >= b;
|
|
});
|
|
|
|
/**
|
|
* Returns whether or not an object has an own property with
|
|
* the specified name
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig s -> {s: x} -> Boolean
|
|
* @param {String} prop The name of the property to check for.
|
|
* @param {Object} obj The object to query.
|
|
* @return {Boolean} Whether the property exists.
|
|
* @example
|
|
*
|
|
* var hasName = R.has('name');
|
|
* hasName({name: 'alice'}); //=> true
|
|
* hasName({name: 'bob'}); //=> true
|
|
* hasName({}); //=> false
|
|
*
|
|
* var point = {x: 0, y: 0};
|
|
* var pointHas = R.has(R.__, point);
|
|
* pointHas('x'); //=> true
|
|
* pointHas('y'); //=> true
|
|
* pointHas('z'); //=> false
|
|
*/
|
|
var has = _curry2(_has);
|
|
|
|
/**
|
|
* Returns whether or not an object or its prototype chain has
|
|
* a property with the specified name
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig s -> {s: x} -> Boolean
|
|
* @param {String} prop The name of the property to check for.
|
|
* @param {Object} obj The object to query.
|
|
* @return {Boolean} Whether the property exists.
|
|
* @example
|
|
*
|
|
* function Rectangle(width, height) {
|
|
* this.width = width;
|
|
* this.height = height;
|
|
* }
|
|
* Rectangle.prototype.area = function() {
|
|
* return this.width * this.height;
|
|
* };
|
|
*
|
|
* var square = new Rectangle(2, 2);
|
|
* R.hasIn('width', square); //=> true
|
|
* R.hasIn('area', square); //=> true
|
|
*/
|
|
var hasIn = _curry2(function (prop, obj) {
|
|
return prop in obj;
|
|
});
|
|
|
|
/**
|
|
* Returns true if its arguments are identical, false otherwise. Values are
|
|
* identical if they reference the same memory. `NaN` is identical to `NaN`;
|
|
* `0` and `-0` are not identical.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig a -> a -> Boolean
|
|
* @param {*} a
|
|
* @param {*} b
|
|
* @return {Boolean}
|
|
* @example
|
|
*
|
|
* var o = {};
|
|
* R.identical(o, o); //=> true
|
|
* R.identical(1, 1); //=> true
|
|
* R.identical(1, '1'); //=> false
|
|
* R.identical([], []); //=> false
|
|
* R.identical(0, -0); //=> false
|
|
* R.identical(NaN, NaN); //=> true
|
|
*/
|
|
// SameValue algorithm
|
|
// Steps 1-5, 7-10
|
|
// Steps 6.b-6.e: +0 != -0
|
|
// Step 6.a: NaN == NaN
|
|
var identical = _curry2(function identical(a, b) {
|
|
// SameValue algorithm
|
|
if (a === b) {
|
|
// Steps 1-5, 7-10
|
|
// Steps 6.b-6.e: +0 != -0
|
|
return a !== 0 || 1 / a === 1 / b;
|
|
} else {
|
|
// Step 6.a: NaN == NaN
|
|
return a !== a && b !== b;
|
|
}
|
|
});
|
|
|
|
/**
|
|
* A function that does nothing but return the parameter supplied to it. Good as a default
|
|
* or placeholder function.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig a -> a
|
|
* @param {*} x The value to return.
|
|
* @return {*} The input value, `x`.
|
|
* @example
|
|
*
|
|
* R.identity(1); //=> 1
|
|
*
|
|
* var obj = {};
|
|
* R.identity(obj) === obj; //=> true
|
|
*/
|
|
var identity = _curry1(_identity);
|
|
|
|
/**
|
|
* Increments its argument.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number
|
|
* @param {Number} n
|
|
* @return {Number}
|
|
* @example
|
|
*
|
|
* R.inc(42); //=> 43
|
|
*/
|
|
var inc = add(1);
|
|
|
|
/**
|
|
* Inserts the sub-list into the list, at index `index`. _Note that this
|
|
* is not destructive_: it returns a copy of the list with the changes.
|
|
* <small>No lists have been harmed in the application of this function.</small>
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> [a] -> [a] -> [a]
|
|
* @param {Number} index The position to insert the sub-list
|
|
* @param {Array} elts The sub-list to insert into the Array
|
|
* @param {Array} list The list to insert the sub-list into
|
|
* @return {Array} A new Array with `elts` inserted starting at `index`.
|
|
* @example
|
|
*
|
|
* R.insertAll(2, ['x','y','z'], [1,2,3,4]); //=> [1,2,'x','y','z',3,4]
|
|
*/
|
|
var insertAll = _curry3(function insertAll(idx, elts, list) {
|
|
idx = idx < list.length && idx >= 0 ? idx : list.length;
|
|
return _concat(_concat(_slice(list, 0, idx), elts), _slice(list, idx));
|
|
});
|
|
|
|
/**
|
|
* See if an object (`val`) is an instance of the supplied constructor.
|
|
* This function will check up the inheritance chain, if any.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Type
|
|
* @sig (* -> {*}) -> a -> Boolean
|
|
* @param {Object} ctor A constructor
|
|
* @param {*} val The value to test
|
|
* @return {Boolean}
|
|
* @example
|
|
*
|
|
* R.is(Object, {}); //=> true
|
|
* R.is(Number, 1); //=> true
|
|
* R.is(Object, 1); //=> false
|
|
* R.is(String, 's'); //=> true
|
|
* R.is(String, new String('')); //=> true
|
|
* R.is(Object, new String('')); //=> true
|
|
* R.is(Object, 's'); //=> false
|
|
* R.is(Number, {}); //=> false
|
|
*/
|
|
var is = _curry2(function is(Ctor, val) {
|
|
return val != null && val.constructor === Ctor || val instanceof Ctor;
|
|
});
|
|
|
|
/**
|
|
* Tests whether or not an object is similar to an array.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Type
|
|
* @category List
|
|
* @sig * -> Boolean
|
|
* @param {*} x The object to test.
|
|
* @return {Boolean} `true` if `x` has a numeric length property and extreme indices defined; `false` otherwise.
|
|
* @example
|
|
*
|
|
* R.isArrayLike([]); //=> true
|
|
* R.isArrayLike(true); //=> false
|
|
* R.isArrayLike({}); //=> false
|
|
* R.isArrayLike({length: 10}); //=> false
|
|
* R.isArrayLike({0: 'zero', 9: 'nine', length: 10}); //=> true
|
|
*/
|
|
var isArrayLike = _curry1(function isArrayLike(x) {
|
|
if (_isArray(x)) {
|
|
return true;
|
|
}
|
|
if (!x) {
|
|
return false;
|
|
}
|
|
if (typeof x !== 'object') {
|
|
return false;
|
|
}
|
|
if (x instanceof String) {
|
|
return false;
|
|
}
|
|
if (x.nodeType === 1) {
|
|
return !!x.length;
|
|
}
|
|
if (x.length === 0) {
|
|
return true;
|
|
}
|
|
if (x.length > 0) {
|
|
return x.hasOwnProperty(0) && x.hasOwnProperty(x.length - 1);
|
|
}
|
|
return false;
|
|
});
|
|
|
|
/**
|
|
* Reports whether the list has zero elements.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig [a] -> Boolean
|
|
* @param {Array} list
|
|
* @return {Boolean}
|
|
* @example
|
|
*
|
|
* R.isEmpty([1, 2, 3]); //=> false
|
|
* R.isEmpty([]); //=> true
|
|
* R.isEmpty(''); //=> true
|
|
* R.isEmpty(null); //=> false
|
|
* R.isEmpty(R.keys({})); //=> true
|
|
* R.isEmpty({}); //=> false ({} does not have a length property)
|
|
* R.isEmpty({length: 0}); //=> true
|
|
*/
|
|
var isEmpty = _curry1(function isEmpty(list) {
|
|
return Object(list).length === 0;
|
|
});
|
|
|
|
/**
|
|
* Checks if the input value is `null` or `undefined`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Type
|
|
* @sig * -> Boolean
|
|
* @param {*} x The value to test.
|
|
* @return {Boolean} `true` if `x` is `undefined` or `null`, otherwise `false`.
|
|
* @example
|
|
*
|
|
* R.isNil(null); //=> true
|
|
* R.isNil(undefined); //=> true
|
|
* R.isNil(0); //=> false
|
|
* R.isNil([]); //=> false
|
|
*/
|
|
var isNil = _curry1(function isNil(x) {
|
|
return x == null;
|
|
});
|
|
|
|
/**
|
|
* Returns a list containing the names of all the enumerable own
|
|
* properties of the supplied object.
|
|
* Note that the order of the output array is not guaranteed to be
|
|
* consistent across different JS platforms.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {k: v} -> [k]
|
|
* @param {Object} obj The object to extract properties from
|
|
* @return {Array} An array of the object's own properties.
|
|
* @example
|
|
*
|
|
* R.keys({a: 1, b: 2, c: 3}); //=> ['a', 'b', 'c']
|
|
*/
|
|
// cover IE < 9 keys issues
|
|
var keys = function () {
|
|
// cover IE < 9 keys issues
|
|
var hasEnumBug = !{ toString: null }.propertyIsEnumerable('toString');
|
|
var nonEnumerableProps = [
|
|
'constructor',
|
|
'valueOf',
|
|
'isPrototypeOf',
|
|
'toString',
|
|
'propertyIsEnumerable',
|
|
'hasOwnProperty',
|
|
'toLocaleString'
|
|
];
|
|
var contains = function contains(list, item) {
|
|
var idx = 0;
|
|
while (idx < list.length) {
|
|
if (list[idx] === item) {
|
|
return true;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return false;
|
|
};
|
|
return typeof Object.keys === 'function' ? _curry1(function keys(obj) {
|
|
return Object(obj) !== obj ? [] : Object.keys(obj);
|
|
}) : _curry1(function keys(obj) {
|
|
if (Object(obj) !== obj) {
|
|
return [];
|
|
}
|
|
var prop, ks = [], nIdx;
|
|
for (prop in obj) {
|
|
if (_has(prop, obj)) {
|
|
ks[ks.length] = prop;
|
|
}
|
|
}
|
|
if (hasEnumBug) {
|
|
nIdx = nonEnumerableProps.length - 1;
|
|
while (nIdx >= 0) {
|
|
prop = nonEnumerableProps[nIdx];
|
|
if (_has(prop, obj) && !contains(ks, prop)) {
|
|
ks[ks.length] = prop;
|
|
}
|
|
nIdx -= 1;
|
|
}
|
|
}
|
|
return ks;
|
|
});
|
|
}();
|
|
|
|
/**
|
|
* Returns a list containing the names of all the
|
|
* properties of the supplied object, including prototype properties.
|
|
* Note that the order of the output array is not guaranteed to be
|
|
* consistent across different JS platforms.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {k: v} -> [k]
|
|
* @param {Object} obj The object to extract properties from
|
|
* @return {Array} An array of the object's own and prototype properties.
|
|
* @example
|
|
*
|
|
* var F = function() { this.x = 'X'; };
|
|
* F.prototype.y = 'Y';
|
|
* var f = new F();
|
|
* R.keysIn(f); //=> ['x', 'y']
|
|
*/
|
|
var keysIn = _curry1(function keysIn(obj) {
|
|
var prop, ks = [];
|
|
for (prop in obj) {
|
|
ks[ks.length] = prop;
|
|
}
|
|
return ks;
|
|
});
|
|
|
|
/**
|
|
* Returns the number of elements in the array by returning `list.length`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> Number
|
|
* @param {Array} list The array to inspect.
|
|
* @return {Number} The length of the array.
|
|
* @example
|
|
*
|
|
* R.length([]); //=> 0
|
|
* R.length([1, 2, 3]); //=> 3
|
|
*/
|
|
var length = _curry1(function length(list) {
|
|
return list != null && is(Number, list.length) ? list.length : NaN;
|
|
});
|
|
|
|
/**
|
|
* Creates a lens. Supply a function to `get` values from inside an object, and a `set`
|
|
* function to change values on an object. (n.b.: This can, and should, be done without
|
|
* mutating the original object!) The lens is a function wrapped around the input `get`
|
|
* function, with the `set` function attached as a property on the wrapper. A `map`
|
|
* function is also attached to the returned function that takes a function to operate
|
|
* on the specified (`get`) property, which is then `set` before returning. The attached
|
|
* `set` and `map` functions are curried.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig (k -> v) -> (v -> a -> *) -> (a -> b)
|
|
* @param {Function} get A function that gets a value by property name
|
|
* @param {Function} set A function that sets a value by property name
|
|
* @return {Function} the returned function has `set` and `map` properties that are
|
|
* also curried functions.
|
|
* @example
|
|
*
|
|
* var headLens = R.lens(
|
|
* function get(arr) { return arr[0]; },
|
|
* function set(val, arr) { return [val].concat(arr.slice(1)); }
|
|
* );
|
|
* headLens([10, 20, 30, 40]); //=> 10
|
|
* headLens.set('mu', [10, 20, 30, 40]); //=> ['mu', 20, 30, 40]
|
|
* headLens.map(function(x) { return x + 1; }, [10, 20, 30, 40]); //=> [11, 20, 30, 40]
|
|
*
|
|
* var phraseLens = R.lens(
|
|
* function get(obj) { return obj.phrase; },
|
|
* function set(val, obj) {
|
|
* var out = R.clone(obj);
|
|
* out.phrase = val;
|
|
* return out;
|
|
* }
|
|
* );
|
|
* var obj1 = { phrase: 'Absolute filth . . . and I LOVED it!'};
|
|
* var obj2 = { phrase: "What's all this, then?"};
|
|
* phraseLens(obj1); // => 'Absolute filth . . . and I LOVED it!'
|
|
* phraseLens(obj2); // => "What's all this, then?"
|
|
* phraseLens.set('Ooh Betty', obj1); //=> { phrase: 'Ooh Betty'}
|
|
* phraseLens.map(R.toUpper, obj2); //=> { phrase: "WHAT'S ALL THIS, THEN?"}
|
|
*/
|
|
var lens = _curry2(function lens(get, set) {
|
|
var lns = function (a) {
|
|
return get(a);
|
|
};
|
|
lns.set = _curry2(set);
|
|
lns.map = _curry2(function (fn, a) {
|
|
return set(fn(get(a)), a);
|
|
});
|
|
return lns;
|
|
});
|
|
|
|
/**
|
|
* Returns a lens associated with the provided object.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig ({} -> v) -> (v -> a -> *) -> {} -> (a -> b)
|
|
* @see R.lens
|
|
* @param {Function} get A function that gets a value by property name
|
|
* @param {Function} set A function that sets a value by property name
|
|
* @param {Object} the actual object of interest
|
|
* @return {Function} the returned function has `set` and `map` properties that are
|
|
* also curried functions.
|
|
* @example
|
|
*
|
|
* var xo = {x: 1};
|
|
* var xoLens = R.lensOn(function get(o) { return o.x; },
|
|
* function set(v) { return {x: v}; },
|
|
* xo);
|
|
* xoLens(); //=> 1
|
|
* xoLens.set(1000); //=> {x: 1000}
|
|
* xoLens.map(R.add(1)); //=> {x: 2}
|
|
*/
|
|
var lensOn = _curry3(function lensOn(get, set, obj) {
|
|
var lns = function () {
|
|
return get(obj);
|
|
};
|
|
lns.set = set;
|
|
lns.map = function (fn) {
|
|
return set(fn(get(obj)));
|
|
};
|
|
return lns;
|
|
});
|
|
|
|
/**
|
|
* Returns true if the first parameter is less than the second.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Boolean
|
|
* @param {Number} a
|
|
* @param {Number} b
|
|
* @return {Boolean} a < b
|
|
* @example
|
|
*
|
|
* R.lt(2, 6); //=> true
|
|
* R.lt(2, 0); //=> false
|
|
* R.lt(2, 2); //=> false
|
|
* R.lt(5)(10); //=> true
|
|
* R.lt(R.__, 5)(10); //=> false // right-sectioned currying
|
|
*/
|
|
var lt = _curry2(_lt);
|
|
|
|
/**
|
|
* Returns true if the first parameter is less than or equal to the second.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Boolean
|
|
* @param {Number} a
|
|
* @param {Number} b
|
|
* @return {Boolean} a <= b
|
|
* @example
|
|
*
|
|
* R.lte(2, 6); //=> true
|
|
* R.lte(2, 0); //=> false
|
|
* R.lte(2, 2); //=> true
|
|
* R.lte(R.__, 2)(1); //=> true
|
|
* R.lte(2)(10); //=> true
|
|
*/
|
|
var lte = _curry2(function lte(a, b) {
|
|
return a <= b;
|
|
});
|
|
|
|
/**
|
|
* The mapAccum function behaves like a combination of map and reduce; it applies a
|
|
* function to each element of a list, passing an accumulating parameter from left to
|
|
* right, and returning a final value of this accumulator together with the new list.
|
|
*
|
|
* The iterator function receives two arguments, *acc* and *value*, and should return
|
|
* a tuple *[acc, value]*.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
|
|
* @param {Function} fn The function to be called on every element of the input `list`.
|
|
* @param {*} acc The accumulator value.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {*} The final, accumulated value.
|
|
* @example
|
|
*
|
|
* var digits = ['1', '2', '3', '4'];
|
|
* var append = function(a, b) {
|
|
* return [a + b, a + b];
|
|
* }
|
|
*
|
|
* R.mapAccum(append, 0, digits); //=> ['01234', ['01', '012', '0123', '01234']]
|
|
*/
|
|
var mapAccum = _curry3(function mapAccum(fn, acc, list) {
|
|
var idx = 0, len = list.length, result = [], tuple = [acc];
|
|
while (idx < len) {
|
|
tuple = fn(tuple[0], list[idx]);
|
|
result[idx] = tuple[1];
|
|
idx += 1;
|
|
}
|
|
return [
|
|
tuple[0],
|
|
result
|
|
];
|
|
});
|
|
|
|
/**
|
|
* The mapAccumRight function behaves like a combination of map and reduce; it applies a
|
|
* function to each element of a list, passing an accumulating parameter from right
|
|
* to left, and returning a final value of this accumulator together with the new list.
|
|
*
|
|
* Similar to `mapAccum`, except moves through the input list from the right to the
|
|
* left.
|
|
*
|
|
* The iterator function receives two arguments, *acc* and *value*, and should return
|
|
* a tuple *[acc, value]*.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
|
|
* @param {Function} fn The function to be called on every element of the input `list`.
|
|
* @param {*} acc The accumulator value.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {*} The final, accumulated value.
|
|
* @example
|
|
*
|
|
* var digits = ['1', '2', '3', '4'];
|
|
* var append = function(a, b) {
|
|
* return [a + b, a + b];
|
|
* }
|
|
*
|
|
* R.mapAccumRight(append, 0, digits); //=> ['04321', ['04321', '0432', '043', '04']]
|
|
*/
|
|
var mapAccumRight = _curry3(function mapAccumRight(fn, acc, list) {
|
|
var idx = list.length - 1, result = [], tuple = [acc];
|
|
while (idx >= 0) {
|
|
tuple = fn(tuple[0], list[idx]);
|
|
result[idx] = tuple[1];
|
|
idx -= 1;
|
|
}
|
|
return [
|
|
tuple[0],
|
|
result
|
|
];
|
|
});
|
|
|
|
/**
|
|
* Like `map`, but but passes additional parameters to the mapping function.
|
|
* `fn` receives three arguments: *(value, index, list)*.
|
|
*
|
|
* Note: `R.mapIndexed` does not skip deleted or unassigned indices (sparse arrays), unlike
|
|
* the native `Array.prototype.map` method. For more details on this behavior, see:
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Description
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a,i,[b] -> b) -> [a] -> [b]
|
|
* @param {Function} fn The function to be called on every element of the input `list`.
|
|
* @param {Array} list The list to be iterated over.
|
|
* @return {Array} The new list.
|
|
* @deprecated since v0.15.0
|
|
* @see R.addIndex
|
|
* @example
|
|
*
|
|
* var squareEnds = function(elt, idx, list) {
|
|
* if (idx === 0 || idx === list.length - 1) {
|
|
* return elt * elt;
|
|
* }
|
|
* return elt;
|
|
* };
|
|
*
|
|
* R.mapIndexed(squareEnds, [8, 5, 3, 0, 9]); //=> [64, 5, 3, 0, 81]
|
|
*/
|
|
var mapIndexed = _curry2(function mapIndexed(fn, list) {
|
|
var idx = 0, len = list.length, result = [];
|
|
while (idx < len) {
|
|
result[idx] = fn(list[idx], idx, list);
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* mathMod behaves like the modulo operator should mathematically, unlike the `%`
|
|
* operator (and by extension, R.modulo). So while "-17 % 5" is -2,
|
|
* mathMod(-17, 5) is 3. mathMod requires Integer arguments, and returns NaN
|
|
* when the modulus is zero or negative.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Number
|
|
* @param {Number} m The dividend.
|
|
* @param {Number} p the modulus.
|
|
* @return {Number} The result of `b mod a`.
|
|
* @see R.moduloBy
|
|
* @example
|
|
*
|
|
* R.mathMod(-17, 5); //=> 3
|
|
* R.mathMod(17, 5); //=> 2
|
|
* R.mathMod(17, -5); //=> NaN
|
|
* R.mathMod(17, 0); //=> NaN
|
|
* R.mathMod(17.2, 5); //=> NaN
|
|
* R.mathMod(17, 5.3); //=> NaN
|
|
*
|
|
* var clock = R.mathMod(R.__, 12);
|
|
* clock(15); //=> 3
|
|
* clock(24); //=> 0
|
|
*
|
|
* var seventeenMod = R.mathMod(17);
|
|
* seventeenMod(3); //=> 2
|
|
* seventeenMod(4); //=> 1
|
|
* seventeenMod(10); //=> 7
|
|
*/
|
|
var mathMod = _curry2(function mathMod(m, p) {
|
|
if (!_isInteger(m)) {
|
|
return NaN;
|
|
}
|
|
if (!_isInteger(p) || p < 1) {
|
|
return NaN;
|
|
}
|
|
return (m % p + p) % p;
|
|
});
|
|
|
|
/**
|
|
* Determines the largest of a list of items as determined by pairwise comparisons from the supplied comparator.
|
|
* Note that this will return undefined if supplied an empty list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig (a -> Number) -> [a] -> a
|
|
* @param {Function} keyFn A comparator function for elements in the list
|
|
* @param {Array} list A list of comparable elements
|
|
* @return {*} The greatest element in the list. `undefined` if the list is empty.
|
|
* @see R.max
|
|
* @example
|
|
*
|
|
* function cmp(obj) { return obj.x; }
|
|
* var a = {x: 1}, b = {x: 2}, c = {x: 3};
|
|
* R.maxBy(cmp, [a, b, c]); //=> {x: 3}
|
|
*/
|
|
var maxBy = _curry2(_createMaxMinBy(_gt));
|
|
|
|
/**
|
|
* Determines the smallest of a list of items as determined by pairwise comparisons from the supplied comparator
|
|
* Note that this will return undefined if supplied an empty list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig (a -> Number) -> [a] -> a
|
|
* @param {Function} keyFn A comparator function for elements in the list
|
|
* @param {Array} list A list of comparable elements
|
|
* @see R.min
|
|
* @return {*} The greatest element in the list. `undefined` if the list is empty.
|
|
* @example
|
|
*
|
|
* function cmp(obj) { return obj.x; }
|
|
* var a = {x: 1}, b = {x: 2}, c = {x: 3};
|
|
* R.minBy(cmp, [a, b, c]); //=> {x: 1}
|
|
*/
|
|
var minBy = _curry2(_createMaxMinBy(_lt));
|
|
|
|
/**
|
|
* Divides the second parameter by the first and returns the remainder.
|
|
* Note that this functions preserves the JavaScript-style behavior for
|
|
* modulo. For mathematical modulo see `mathMod`
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Number
|
|
* @param {Number} a The value to the divide.
|
|
* @param {Number} b The pseudo-modulus
|
|
* @return {Number} The result of `b % a`.
|
|
* @see R.mathMod
|
|
* @example
|
|
*
|
|
* R.modulo(17, 3); //=> 2
|
|
* // JS behavior:
|
|
* R.modulo(-17, 3); //=> -2
|
|
* R.modulo(17, -3); //=> 2
|
|
*
|
|
* var isOdd = R.modulo(R.__, 2);
|
|
* isOdd(42); //=> 0
|
|
* isOdd(21); //=> 1
|
|
*/
|
|
var modulo = _curry2(function modulo(a, b) {
|
|
return a % b;
|
|
});
|
|
|
|
/**
|
|
* Multiplies two numbers. Equivalent to `a * b` but curried.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Number
|
|
* @param {Number} a The first value.
|
|
* @param {Number} b The second value.
|
|
* @return {Number} The result of `a * b`.
|
|
* @example
|
|
*
|
|
* var double = R.multiply(2);
|
|
* var triple = R.multiply(3);
|
|
* double(3); //=> 6
|
|
* triple(4); //=> 12
|
|
* R.multiply(2, 5); //=> 10
|
|
*/
|
|
var multiply = _curry2(_multiply);
|
|
|
|
/**
|
|
* Wraps a function of any arity (including nullary) in a function that accepts exactly `n`
|
|
* parameters. Any extraneous parameters will not be passed to the supplied function.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig Number -> (* -> a) -> (* -> a)
|
|
* @param {Number} n The desired arity of the new function.
|
|
* @param {Function} fn The function to wrap.
|
|
* @return {Function} A new function wrapping `fn`. The new function is guaranteed to be of
|
|
* arity `n`.
|
|
* @example
|
|
*
|
|
* var takesTwoArgs = function(a, b) {
|
|
* return [a, b];
|
|
* };
|
|
* takesTwoArgs.length; //=> 2
|
|
* takesTwoArgs(1, 2); //=> [1, 2]
|
|
*
|
|
* var takesOneArg = R.nAry(1, takesTwoArgs);
|
|
* takesOneArg.length; //=> 1
|
|
* // Only `n` arguments are passed to the wrapped function
|
|
* takesOneArg(1, 2); //=> [1, undefined]
|
|
*/
|
|
var nAry = _curry2(function (n, fn) {
|
|
switch (n) {
|
|
case 0:
|
|
return function () {
|
|
return fn.call(this);
|
|
};
|
|
case 1:
|
|
return function (a0) {
|
|
return fn.call(this, a0);
|
|
};
|
|
case 2:
|
|
return function (a0, a1) {
|
|
return fn.call(this, a0, a1);
|
|
};
|
|
case 3:
|
|
return function (a0, a1, a2) {
|
|
return fn.call(this, a0, a1, a2);
|
|
};
|
|
case 4:
|
|
return function (a0, a1, a2, a3) {
|
|
return fn.call(this, a0, a1, a2, a3);
|
|
};
|
|
case 5:
|
|
return function (a0, a1, a2, a3, a4) {
|
|
return fn.call(this, a0, a1, a2, a3, a4);
|
|
};
|
|
case 6:
|
|
return function (a0, a1, a2, a3, a4, a5) {
|
|
return fn.call(this, a0, a1, a2, a3, a4, a5);
|
|
};
|
|
case 7:
|
|
return function (a0, a1, a2, a3, a4, a5, a6) {
|
|
return fn.call(this, a0, a1, a2, a3, a4, a5, a6);
|
|
};
|
|
case 8:
|
|
return function (a0, a1, a2, a3, a4, a5, a6, a7) {
|
|
return fn.call(this, a0, a1, a2, a3, a4, a5, a6, a7);
|
|
};
|
|
case 9:
|
|
return function (a0, a1, a2, a3, a4, a5, a6, a7, a8) {
|
|
return fn.call(this, a0, a1, a2, a3, a4, a5, a6, a7, a8);
|
|
};
|
|
case 10:
|
|
return function (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
|
|
return fn.call(this, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
};
|
|
default:
|
|
throw new Error('First argument to nAry must be a non-negative integer no greater than ten');
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Negates its argument.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number
|
|
* @param {Number} n
|
|
* @return {Number}
|
|
* @example
|
|
*
|
|
* R.negate(42); //=> -42
|
|
*/
|
|
var negate = _curry1(function negate(n) {
|
|
return -n;
|
|
});
|
|
|
|
/**
|
|
* A function that returns the `!` of its argument. It will return `true` when
|
|
* passed false-y value, and `false` when passed a truth-y one.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig * -> Boolean
|
|
* @param {*} a any value
|
|
* @return {Boolean} the logical inverse of passed argument.
|
|
* @see R.complement
|
|
* @example
|
|
*
|
|
* R.not(true); //=> false
|
|
* R.not(false); //=> true
|
|
* R.not(0); => true
|
|
* R.not(1); => false
|
|
*/
|
|
var not = _curry1(function not(a) {
|
|
return !a;
|
|
});
|
|
|
|
/**
|
|
* Returns the nth element in a list.
|
|
* If n is negative the element at index length + n is returned.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> [a] -> a
|
|
* @param {Number} idx
|
|
* @param {Array} list
|
|
* @return {*} The nth element of the list.
|
|
* @example
|
|
*
|
|
* var list = ['foo', 'bar', 'baz', 'quux'];
|
|
* R.nth(1, list); //=> 'bar'
|
|
* R.nth(-1, list); //=> 'quux'
|
|
* R.nth(-99, list); //=> undefined
|
|
*/
|
|
var nth = _curry2(_nth);
|
|
|
|
/**
|
|
* Returns a function which returns its nth argument.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig Number -> *... -> *
|
|
* @param {Number} n
|
|
* @return {Function}
|
|
* @example
|
|
*
|
|
* R.nthArg(1)('a', 'b', 'c'); //=> 'b'
|
|
* R.nthArg(-1)('a', 'b', 'c'); //=> 'c'
|
|
*/
|
|
var nthArg = _curry1(function nthArg(n) {
|
|
return function () {
|
|
return _nth(n, arguments);
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Returns the nth character of the given string.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig Number -> String -> String
|
|
* @param {Number} n
|
|
* @param {String} str
|
|
* @return {String}
|
|
* @example
|
|
*
|
|
* R.nthChar(2, 'Ramda'); //=> 'm'
|
|
* R.nthChar(-2, 'Ramda'); //=> 'd'
|
|
*/
|
|
var nthChar = _curry2(function nthChar(n, str) {
|
|
return str.charAt(n < 0 ? str.length + n : n);
|
|
});
|
|
|
|
/**
|
|
* Returns the character code of the nth character of the given string.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig Number -> String -> Number
|
|
* @param {Number} n
|
|
* @param {String} str
|
|
* @return {Number}
|
|
* @example
|
|
*
|
|
* R.nthCharCode(2, 'Ramda'); //=> 'm'.charCodeAt(0)
|
|
* R.nthCharCode(-2, 'Ramda'); //=> 'd'.charCodeAt(0)
|
|
*/
|
|
var nthCharCode = _curry2(function nthCharCode(n, str) {
|
|
return str.charCodeAt(n < 0 ? str.length + n : n);
|
|
});
|
|
|
|
/**
|
|
* Returns a singleton array containing the value provided.
|
|
*
|
|
* Note this `of` is different from the ES6 `of`; See
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig a -> [a]
|
|
* @param {*} x any value
|
|
* @return {Array} An array wrapping `x`.
|
|
* @example
|
|
*
|
|
* R.of(null); //=> [null]
|
|
* R.of([42]); //=> [[42]]
|
|
*/
|
|
var of = _curry1(function of(x) {
|
|
return [x];
|
|
});
|
|
|
|
/**
|
|
* Accepts a function `fn` and returns a function that guards invocation of `fn` such that
|
|
* `fn` can only ever be called once, no matter how many times the returned function is
|
|
* invoked.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (a... -> b) -> (a... -> b)
|
|
* @param {Function} fn The function to wrap in a call-only-once wrapper.
|
|
* @return {Function} The wrapped function.
|
|
* @example
|
|
*
|
|
* var addOneOnce = R.once(function(x){ return x + 1; });
|
|
* addOneOnce(10); //=> 11
|
|
* addOneOnce(addOneOnce(50)); //=> 11
|
|
*/
|
|
var once = _curry1(function once(fn) {
|
|
var called = false, result;
|
|
return function () {
|
|
if (called) {
|
|
return result;
|
|
}
|
|
called = true;
|
|
result = fn.apply(this, arguments);
|
|
return result;
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Retrieve the value at a given path.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig [String] -> {*} -> *
|
|
* @param {Array} path The path to use.
|
|
* @return {*} The data at `path`.
|
|
* @example
|
|
*
|
|
* R.path(['a', 'b'], {a: {b: 2}}); //=> 2
|
|
*/
|
|
var path = _curry2(_path);
|
|
|
|
/**
|
|
* Returns a partial copy of an object containing only the keys specified. If the key does not exist, the
|
|
* property is ignored.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig [k] -> {k: v} -> {k: v}
|
|
* @param {Array} names an array of String property names to copy onto a new object
|
|
* @param {Object} obj The object to copy from
|
|
* @return {Object} A new object with only properties from `names` on it.
|
|
* @example
|
|
*
|
|
* R.pick(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, d: 4}
|
|
* R.pick(['a', 'e', 'f'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1}
|
|
*/
|
|
var pick = _curry2(function pick(names, obj) {
|
|
var result = {};
|
|
var idx = 0;
|
|
while (idx < names.length) {
|
|
if (names[idx] in obj) {
|
|
result[names[idx]] = obj[names[idx]];
|
|
}
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Similar to `pick` except that this one includes a `key: undefined` pair for properties that don't exist.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig [k] -> {k: v} -> {k: v}
|
|
* @param {Array} names an array of String property names to copy onto a new object
|
|
* @param {Object} obj The object to copy from
|
|
* @return {Object} A new object with only properties from `names` on it.
|
|
* @see R.pick
|
|
* @example
|
|
*
|
|
* R.pickAll(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, d: 4}
|
|
* R.pickAll(['a', 'e', 'f'], {a: 1, b: 2, c: 3, d: 4}); //=> {a: 1, e: undefined, f: undefined}
|
|
*/
|
|
var pickAll = _curry2(function pickAll(names, obj) {
|
|
var result = {};
|
|
var idx = 0;
|
|
var len = names.length;
|
|
while (idx < len) {
|
|
var name = names[idx];
|
|
result[name] = obj[name];
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Returns a partial copy of an object containing only the keys that
|
|
* satisfy the supplied predicate.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig (v, k -> Boolean) -> {k: v} -> {k: v}
|
|
* @param {Function} pred A predicate to determine whether or not a key
|
|
* should be included on the output object.
|
|
* @param {Object} obj The object to copy from
|
|
* @return {Object} A new object with only properties that satisfy `pred`
|
|
* on it.
|
|
* @see R.pick
|
|
* @example
|
|
*
|
|
* var isUpperCase = function(val, key) { return key.toUpperCase() === key; }
|
|
* R.pickBy(isUpperCase, {a: 1, b: 2, A: 3, B: 4}); //=> {A: 3, B: 4}
|
|
*/
|
|
var pickBy = _curry2(function pickBy(test, obj) {
|
|
var result = {};
|
|
for (var prop in obj) {
|
|
if (test(obj[prop], prop, obj)) {
|
|
result[prop] = obj[prop];
|
|
}
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Returns a new list with the given element at the front, followed by the contents of the
|
|
* list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig a -> [a] -> [a]
|
|
* @param {*} el The item to add to the head of the output list.
|
|
* @param {Array} list The array to add to the tail of the output list.
|
|
* @return {Array} A new array.
|
|
* @example
|
|
*
|
|
* R.prepend('fee', ['fi', 'fo', 'fum']); //=> ['fee', 'fi', 'fo', 'fum']
|
|
*/
|
|
var prepend = _curry2(_prepend);
|
|
|
|
/**
|
|
* Returns a function that when supplied an object returns the indicated property of that object, if it exists.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig s -> {s: a} -> a
|
|
* @param {String} p The property name
|
|
* @param {Object} obj The object to query
|
|
* @return {*} The value at `obj.p`.
|
|
* @example
|
|
*
|
|
* R.prop('x', {x: 100}); //=> 100
|
|
* R.prop('x', {}); //=> undefined
|
|
*/
|
|
var prop = _curry2(function prop(p, obj) {
|
|
return obj[p];
|
|
});
|
|
|
|
/**
|
|
* If the given, non-null object has an own property with the specified name,
|
|
* returns the value of that property.
|
|
* Otherwise returns the provided default value.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig a -> String -> Object -> a
|
|
* @param {*} val The default value.
|
|
* @param {String} p The name of the property to return.
|
|
* @param {Object} obj The object to query.
|
|
* @return {*} The value of given property of the supplied object or the default value.
|
|
* @example
|
|
*
|
|
* var alice = {
|
|
* name: 'ALICE',
|
|
* age: 101
|
|
* };
|
|
* var favorite = R.prop('favoriteLibrary');
|
|
* var favoriteWithDefault = R.propOr('Ramda', 'favoriteLibrary');
|
|
*
|
|
* favorite(alice); //=> undefined
|
|
* favoriteWithDefault(alice); //=> 'Ramda'
|
|
*/
|
|
var propOr = _curry3(function propOr(val, p, obj) {
|
|
return obj != null && _has(p, obj) ? obj[p] : val;
|
|
});
|
|
|
|
/**
|
|
* Acts as multiple `get`: array of keys in, array of values out. Preserves order.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig [k] -> {k: v} -> [v]
|
|
* @param {Array} ps The property names to fetch
|
|
* @param {Object} obj The object to query
|
|
* @return {Array} The corresponding values or partially applied function.
|
|
* @example
|
|
*
|
|
* R.props(['x', 'y'], {x: 1, y: 2}); //=> [1, 2]
|
|
* R.props(['c', 'a', 'b'], {b: 2, a: 1}); //=> [undefined, 1, 2]
|
|
*
|
|
* var fullName = R.compose(R.join(' '), R.props(['first', 'last']));
|
|
* fullName({last: 'Bullet-Tooth', age: 33, first: 'Tony'}); //=> 'Tony Bullet-Tooth'
|
|
*/
|
|
var props = _curry2(function props(ps, obj) {
|
|
var len = ps.length;
|
|
var out = [];
|
|
var idx = 0;
|
|
while (idx < len) {
|
|
out[idx] = obj[ps[idx]];
|
|
idx += 1;
|
|
}
|
|
return out;
|
|
});
|
|
|
|
/**
|
|
* Returns a list of numbers from `from` (inclusive) to `to`
|
|
* (exclusive).
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> Number -> [Number]
|
|
* @param {Number} from The first number in the list.
|
|
* @param {Number} to One more than the last number in the list.
|
|
* @return {Array} The list of numbers in tthe set `[a, b)`.
|
|
* @example
|
|
*
|
|
* R.range(1, 5); //=> [1, 2, 3, 4]
|
|
* R.range(50, 53); //=> [50, 51, 52]
|
|
*/
|
|
var range = _curry2(function range(from, to) {
|
|
var result = [];
|
|
var n = from;
|
|
while (n < to) {
|
|
result[result.length] = n;
|
|
n += 1;
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Like `reduce`, but passes additional parameters to the predicate function.
|
|
*
|
|
* The iterator function receives four values: *(acc, value, index, list)*
|
|
*
|
|
* Note: `R.reduceIndexed` does not skip deleted or unassigned indices (sparse arrays),
|
|
* unlike the native `Array.prototype.reduce` method. For more details on this behavior,
|
|
* see:
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Description
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a,b,i,[b] -> a) -> a -> [b] -> a
|
|
* @param {Function} fn The iterator function. Receives four values: the accumulator, the
|
|
* current element from `list`, that element's index, and the entire `list` itself.
|
|
* @param {*} acc The accumulator value.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {*} The final, accumulated value.
|
|
* @deprecated since v0.15.0
|
|
* @see R.addIndex
|
|
* @example
|
|
*
|
|
* var letters = ['a', 'b', 'c'];
|
|
* var objectify = function(accObject, elem, idx, list) {
|
|
* accObject[elem] = idx;
|
|
* return accObject;
|
|
* };
|
|
*
|
|
* R.reduceIndexed(objectify, {}, letters); //=> { 'a': 0, 'b': 1, 'c': 2 }
|
|
*/
|
|
var reduceIndexed = _curry3(function reduceIndexed(fn, acc, list) {
|
|
var idx = 0, len = list.length;
|
|
while (idx < len) {
|
|
acc = fn(acc, list[idx], idx, list);
|
|
idx += 1;
|
|
}
|
|
return acc;
|
|
});
|
|
|
|
/**
|
|
* Returns a single item by iterating through the list, successively calling the iterator
|
|
* function and passing it an accumulator value and the current value from the array, and
|
|
* then passing the result to the next call.
|
|
*
|
|
* Similar to `reduce`, except moves through the input list from the right to the left.
|
|
*
|
|
* The iterator function receives two values: *(acc, value)*
|
|
*
|
|
* Note: `R.reduceRight` does not skip deleted or unassigned indices (sparse arrays), unlike
|
|
* the native `Array.prototype.reduce` method. For more details on this behavior, see:
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight#Description
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a,b -> a) -> a -> [b] -> a
|
|
* @param {Function} fn The iterator function. Receives two values, the accumulator and the
|
|
* current element from the array.
|
|
* @param {*} acc The accumulator value.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {*} The final, accumulated value.
|
|
* @example
|
|
*
|
|
* var pairs = [ ['a', 1], ['b', 2], ['c', 3] ];
|
|
* var flattenPairs = function(acc, pair) {
|
|
* return acc.concat(pair);
|
|
* };
|
|
*
|
|
* R.reduceRight(flattenPairs, [], pairs); //=> [ 'c', 3, 'b', 2, 'a', 1 ]
|
|
*/
|
|
var reduceRight = _curry3(function reduceRight(fn, acc, list) {
|
|
var idx = list.length - 1;
|
|
while (idx >= 0) {
|
|
acc = fn(acc, list[idx]);
|
|
idx -= 1;
|
|
}
|
|
return acc;
|
|
});
|
|
|
|
/**
|
|
* Like `reduceRight`, but passes additional parameters to the predicate function. Moves through
|
|
* the input list from the right to the left.
|
|
*
|
|
* The iterator function receives four values: *(acc, value, index, list)*.
|
|
*
|
|
* Note: `R.reduceRightIndexed` does not skip deleted or unassigned indices (sparse arrays),
|
|
* unlike the native `Array.prototype.reduce` method. For more details on this behavior,
|
|
* see:
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight#Description
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a,b,i,[b] -> a -> [b] -> a
|
|
* @param {Function} fn The iterator function. Receives four values: the accumulator, the
|
|
* current element from `list`, that element's index, and the entire `list` itself.
|
|
* @param {*} acc The accumulator value.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {*} The final, accumulated value.
|
|
* @deprecated since v0.15.0
|
|
* @see R.addIndex
|
|
* @example
|
|
*
|
|
* var letters = ['a', 'b', 'c'];
|
|
* var objectify = function(accObject, elem, idx, list) {
|
|
* accObject[elem] = idx;
|
|
* return accObject;
|
|
* };
|
|
*
|
|
* R.reduceRightIndexed(objectify, {}, letters); //=> { 'c': 2, 'b': 1, 'a': 0 }
|
|
*/
|
|
var reduceRightIndexed = _curry3(function reduceRightIndexed(fn, acc, list) {
|
|
var idx = list.length - 1;
|
|
while (idx >= 0) {
|
|
acc = fn(acc, list[idx], idx, list);
|
|
idx -= 1;
|
|
}
|
|
return acc;
|
|
});
|
|
|
|
/**
|
|
* Returns a value wrapped to indicate that it is the final value of the
|
|
* reduce and transduce functions. The returned value
|
|
* should be considered a black box: the internal structure is not
|
|
* guaranteed to be stable.
|
|
*
|
|
* Note: this optimization is unavailable to functions not explicitly listed
|
|
* above. For instance, it is not currently supported by reduceIndexed,
|
|
* reduceRight, or reduceRightIndexed.
|
|
* @see R.reduce
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig a -> *
|
|
* @param {*} x The final value of the reduce.
|
|
* @return {*} The wrapped value.
|
|
* @example
|
|
*
|
|
* R.reduce(
|
|
* R.pipe(R.add, R.ifElse(R.lte(10), R.reduced, R.identity)),
|
|
* 0,
|
|
* [1, 2, 3, 4, 5]) // 10
|
|
*/
|
|
var reduced = _curry1(_reduced);
|
|
|
|
/**
|
|
* Like `reject`, but passes additional parameters to the predicate function. The predicate
|
|
* function is passed three arguments: *(value, index, list)*.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a, i, [a] -> Boolean) -> [a] -> [a]
|
|
* @param {Function} fn The function called per iteration.
|
|
* @param {Array} list The collection to iterate over.
|
|
* @return {Array} The new filtered array.
|
|
* @deprecated since v0.15.0
|
|
* @see R.addIndex
|
|
* @example
|
|
*
|
|
* var lastTwo = function(val, idx, list) {
|
|
* return list.length - idx <= 2;
|
|
* };
|
|
*
|
|
* R.rejectIndexed(lastTwo, [8, 6, 7, 5, 3, 0, 9]); //=> [8, 6, 7, 5, 3]
|
|
*/
|
|
var rejectIndexed = _curry2(function rejectIndexed(fn, list) {
|
|
return _filterIndexed(_complement(fn), list);
|
|
});
|
|
|
|
/**
|
|
* Removes the sub-list of `list` starting at index `start` and containing
|
|
* `count` elements. _Note that this is not destructive_: it returns a
|
|
* copy of the list with the changes.
|
|
* <small>No lists have been harmed in the application of this function.</small>
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> Number -> [a] -> [a]
|
|
* @param {Number} start The position to start removing elements
|
|
* @param {Number} count The number of elements to remove
|
|
* @param {Array} list The list to remove from
|
|
* @return {Array} A new Array with `count` elements from `start` removed.
|
|
* @example
|
|
*
|
|
* R.remove(2, 3, [1,2,3,4,5,6,7,8]); //=> [1,2,6,7,8]
|
|
*/
|
|
var remove = _curry3(function remove(start, count, list) {
|
|
return _concat(_slice(list, 0, Math.min(start, list.length)), _slice(list, Math.min(list.length, start + count)));
|
|
});
|
|
|
|
/**
|
|
* Replace a substring or regex match in a string with a replacement.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig RegExp|String -> String -> String -> String
|
|
* @param {RegExp|String} pattern A regular expression or a substring to match.
|
|
* @param {String} replacement The string to replace the matches with.
|
|
* @param {String} str The String to do the search and replacement in.
|
|
* @return {String} The result.
|
|
* @example
|
|
*
|
|
* R.replace('foo', 'bar', 'foo foo foo'); //=> 'bar foo foo'
|
|
* R.replace(/foo/, 'bar', 'foo foo foo'); //=> 'bar foo foo'
|
|
*
|
|
* // Use the "g" (global) flag to replace all occurrences:
|
|
* R.replace(/foo/g, 'bar', 'foo foo foo'); //=> 'bar bar bar'
|
|
*/
|
|
var replace = _curry3(function replace(regex, replacement, str) {
|
|
return str.replace(regex, replacement);
|
|
});
|
|
|
|
/**
|
|
* Returns a new list with the same elements as the original list, just
|
|
* in the reverse order.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [a]
|
|
* @param {Array} list The list to reverse.
|
|
* @return {Array} A copy of the list in reverse order.
|
|
* @example
|
|
*
|
|
* R.reverse([1, 2, 3]); //=> [3, 2, 1]
|
|
* R.reverse([1, 2]); //=> [2, 1]
|
|
* R.reverse([1]); //=> [1]
|
|
* R.reverse([]); //=> []
|
|
*/
|
|
var reverse = _curry1(function reverse(list) {
|
|
return _slice(list).reverse();
|
|
});
|
|
|
|
/**
|
|
* Scan is similar to reduce, but returns a list of successively reduced values from the left
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a,b -> a) -> a -> [b] -> [a]
|
|
* @param {Function} fn The iterator function. Receives two values, the accumulator and the
|
|
* current element from the array
|
|
* @param {*} acc The accumulator value.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {Array} A list of all intermediately reduced values.
|
|
* @example
|
|
*
|
|
* var numbers = [1, 2, 3, 4];
|
|
* var factorials = R.scan(R.multiply, 1, numbers); //=> [1, 1, 2, 6, 24]
|
|
*/
|
|
var scan = _curry3(function scan(fn, acc, list) {
|
|
var idx = 0, len = list.length, result = [acc];
|
|
while (idx < len) {
|
|
acc = fn(acc, list[idx]);
|
|
result[idx + 1] = acc;
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Returns a copy of the list, sorted according to the comparator function, which should accept two values at a
|
|
* time and return a negative number if the first value is smaller, a positive number if it's larger, and zero
|
|
* if they are equal. Please note that this is a **copy** of the list. It does not modify the original.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a,a -> Number) -> [a] -> [a]
|
|
* @param {Function} comparator A sorting function :: a -> b -> Int
|
|
* @param {Array} list The list to sort
|
|
* @return {Array} a new array with its elements sorted by the comparator function.
|
|
* @example
|
|
*
|
|
* var diff = function(a, b) { return a - b; };
|
|
* R.sort(diff, [4,2,7,5]); //=> [2, 4, 5, 7]
|
|
*/
|
|
var sort = _curry2(function sort(comparator, list) {
|
|
return _slice(list).sort(comparator);
|
|
});
|
|
|
|
/**
|
|
* Sorts the list according to the supplied function.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig Ord b => (a -> b) -> [a] -> [a]
|
|
* @param {Function} fn
|
|
* @param {Array} list The list to sort.
|
|
* @return {Array} A new list sorted by the keys generated by `fn`.
|
|
* @example
|
|
*
|
|
* var sortByFirstItem = R.sortBy(prop(0));
|
|
* var sortByNameCaseInsensitive = R.sortBy(compose(R.toLower, prop('name')));
|
|
* var pairs = [[-1, 1], [-2, 2], [-3, 3]];
|
|
* sortByFirstItem(pairs); //=> [[-3, 3], [-2, 2], [-1, 1]]
|
|
* var alice = {
|
|
* name: 'ALICE',
|
|
* age: 101
|
|
* };
|
|
* var bob = {
|
|
* name: 'Bob',
|
|
* age: -10
|
|
* };
|
|
* var clara = {
|
|
* name: 'clara',
|
|
* age: 314.159
|
|
* };
|
|
* var people = [clara, bob, alice];
|
|
* sortByNameCaseInsensitive(people); //=> [alice, bob, clara]
|
|
*/
|
|
var sortBy = _curry2(function sortBy(fn, list) {
|
|
return _slice(list).sort(function (a, b) {
|
|
var aa = fn(a);
|
|
var bb = fn(b);
|
|
return aa < bb ? -1 : aa > bb ? 1 : 0;
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Finds the first index of a substring in a string, returning -1 if it's not present
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig String -> String -> Number
|
|
* @param {String} c A string to find.
|
|
* @param {String} str The string to search in
|
|
* @return {Number} The first index of `c` or -1 if not found.
|
|
* @deprecated since v0.15.0
|
|
* @example
|
|
*
|
|
* R.strIndexOf('c', 'abcdefg'); //=> 2
|
|
*/
|
|
var strIndexOf = _curry2(function strIndexOf(c, str) {
|
|
return str.indexOf(c);
|
|
});
|
|
|
|
/**
|
|
*
|
|
* Finds the last index of a substring in a string, returning -1 if it's not present
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig String -> String -> Number
|
|
* @param {String} c A string to find.
|
|
* @param {String} str The string to search in
|
|
* @return {Number} The last index of `c` or -1 if not found.
|
|
* @deprecated since v0.15.0
|
|
* @example
|
|
*
|
|
* R.strLastIndexOf('a', 'banana split'); //=> 5
|
|
*/
|
|
var strLastIndexOf = _curry2(function (c, str) {
|
|
return str.lastIndexOf(c);
|
|
});
|
|
|
|
/**
|
|
* Subtracts two numbers. Equivalent to `a - b` but curried.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig Number -> Number -> Number
|
|
* @param {Number} a The first value.
|
|
* @param {Number} b The second value.
|
|
* @return {Number} The result of `a - b`.
|
|
* @example
|
|
*
|
|
* R.subtract(10, 8); //=> 2
|
|
*
|
|
* var minus5 = R.subtract(R.__, 5);
|
|
* minus5(17); //=> 12
|
|
*
|
|
* var complementaryAngle = R.subtract(90);
|
|
* complementaryAngle(30); //=> 60
|
|
* complementaryAngle(72); //=> 18
|
|
*/
|
|
var subtract = _curry2(function subtract(a, b) {
|
|
return a - b;
|
|
});
|
|
|
|
/**
|
|
* Runs the given function with the supplied object, then returns the object.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (a -> *) -> a -> a
|
|
* @param {Function} fn The function to call with `x`. The return value of `fn` will be thrown away.
|
|
* @param {*} x
|
|
* @return {*} `x`.
|
|
* @example
|
|
*
|
|
* var sayX = function(x) { console.log('x is ' + x); };
|
|
* R.tap(sayX, 100); //=> 100
|
|
* //-> 'x is 100'
|
|
*/
|
|
var tap = _curry2(function tap(fn, x) {
|
|
fn(x);
|
|
return x;
|
|
});
|
|
|
|
/**
|
|
* Determines whether a given string matches a given regular expression.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig RegExp -> String -> Boolean
|
|
* @param {RegExp} pattern
|
|
* @param {String} str
|
|
* @return {Boolean}
|
|
* @example
|
|
*
|
|
* R.test(/^x/, 'xyz'); //=> true
|
|
* R.test(/^y/, 'xyz'); //=> false
|
|
*/
|
|
var test = _curry2(function test(pattern, str) {
|
|
return _cloneRegExp(pattern).test(str);
|
|
});
|
|
|
|
/**
|
|
* Calls an input function `n` times, returning an array containing the results of those
|
|
* function calls.
|
|
*
|
|
* `fn` is passed one argument: The current value of `n`, which begins at `0` and is
|
|
* gradually incremented to `n - 1`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (i -> a) -> i -> [a]
|
|
* @param {Function} fn The function to invoke. Passed one argument, the current value of `n`.
|
|
* @param {Number} n A value between `0` and `n - 1`. Increments after each function call.
|
|
* @return {Array} An array containing the return values of all calls to `fn`.
|
|
* @example
|
|
*
|
|
* R.times(R.identity, 5); //=> [0, 1, 2, 3, 4]
|
|
*/
|
|
var times = _curry2(function times(fn, n) {
|
|
var len = Number(n);
|
|
var list = new Array(len);
|
|
var idx = 0;
|
|
while (idx < len) {
|
|
list[idx] = fn(idx);
|
|
idx += 1;
|
|
}
|
|
return list;
|
|
});
|
|
|
|
/**
|
|
* Converts an object into an array of key, value arrays.
|
|
* Only the object's own properties are used.
|
|
* Note that the order of the output array is not guaranteed to be
|
|
* consistent across different JS platforms.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {String: *} -> [[String,*]]
|
|
* @param {Object} obj The object to extract from
|
|
* @return {Array} An array of key, value arrays from the object's own properties.
|
|
* @example
|
|
*
|
|
* R.toPairs({a: 1, b: 2, c: 3}); //=> [['a', 1], ['b', 2], ['c', 3]]
|
|
*/
|
|
var toPairs = _curry1(function toPairs(obj) {
|
|
var pairs = [];
|
|
for (var prop in obj) {
|
|
if (_has(prop, obj)) {
|
|
pairs[pairs.length] = [
|
|
prop,
|
|
obj[prop]
|
|
];
|
|
}
|
|
}
|
|
return pairs;
|
|
});
|
|
|
|
/**
|
|
* Converts an object into an array of key, value arrays.
|
|
* The object's own properties and prototype properties are used.
|
|
* Note that the order of the output array is not guaranteed to be
|
|
* consistent across different JS platforms.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {String: *} -> [[String,*]]
|
|
* @param {Object} obj The object to extract from
|
|
* @return {Array} An array of key, value arrays from the object's own
|
|
* and prototype properties.
|
|
* @example
|
|
*
|
|
* var F = function() { this.x = 'X'; };
|
|
* F.prototype.y = 'Y';
|
|
* var f = new F();
|
|
* R.toPairsIn(f); //=> [['x','X'], ['y','Y']]
|
|
*/
|
|
var toPairsIn = _curry1(function toPairsIn(obj) {
|
|
var pairs = [];
|
|
for (var prop in obj) {
|
|
pairs[pairs.length] = [
|
|
prop,
|
|
obj[prop]
|
|
];
|
|
}
|
|
return pairs;
|
|
});
|
|
|
|
/**
|
|
* Removes (strips) whitespace from both ends of the string.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig String -> String
|
|
* @param {String} str The string to trim.
|
|
* @return {String} Trimmed version of `str`.
|
|
* @example
|
|
*
|
|
* R.trim(' xyz '); //=> 'xyz'
|
|
* R.map(R.trim, R.split(',', 'x, y, z')); //=> ['x', 'y', 'z']
|
|
*/
|
|
var trim = function () {
|
|
var ws = '\t\n\x0B\f\r \xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + '\u2029\uFEFF';
|
|
var zeroWidth = '\u200B';
|
|
var hasProtoTrim = typeof String.prototype.trim === 'function';
|
|
if (!hasProtoTrim || (ws.trim() || !zeroWidth.trim())) {
|
|
return _curry1(function trim(str) {
|
|
var beginRx = new RegExp('^[' + ws + '][' + ws + ']*');
|
|
var endRx = new RegExp('[' + ws + '][' + ws + ']*$');
|
|
return str.replace(beginRx, '').replace(endRx, '');
|
|
});
|
|
} else {
|
|
return _curry1(function trim(str) {
|
|
return str.trim();
|
|
});
|
|
}
|
|
}();
|
|
|
|
/**
|
|
* Gives a single-word string description of the (native) type of a value, returning such
|
|
* answers as 'Object', 'Number', 'Array', or 'Null'. Does not attempt to distinguish user
|
|
* Object types any further, reporting them all as 'Object'.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Type
|
|
* @sig (* -> {*}) -> String
|
|
* @param {*} val The value to test
|
|
* @return {String}
|
|
* @example
|
|
*
|
|
* R.type({}); //=> "Object"
|
|
* R.type(1); //=> "Number"
|
|
* R.type(false); //=> "Boolean"
|
|
* R.type('s'); //=> "String"
|
|
* R.type(null); //=> "Null"
|
|
* R.type([]); //=> "Array"
|
|
* R.type(/[A-z]/); //=> "RegExp"
|
|
*/
|
|
var type = _curry1(function type(val) {
|
|
return val === null ? 'Null' : val === undefined ? 'Undefined' : Object.prototype.toString.call(val).slice(8, -1);
|
|
});
|
|
|
|
/**
|
|
* Takes a function `fn`, which takes a single array argument, and returns
|
|
* a function which:
|
|
*
|
|
* - takes any number of positional arguments;
|
|
* - passes these arguments to `fn` as an array; and
|
|
* - returns the result.
|
|
*
|
|
* In other words, R.unapply derives a variadic function from a function
|
|
* which takes an array. R.unapply is the inverse of R.apply.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig ([*...] -> a) -> (*... -> a)
|
|
* @param {Function} fn
|
|
* @return {Function}
|
|
* @see R.apply
|
|
* @example
|
|
*
|
|
* R.unapply(JSON.stringify)(1, 2, 3); //=> '[1,2,3]'
|
|
*/
|
|
var unapply = _curry1(function unapply(fn) {
|
|
return function () {
|
|
return fn(_slice(arguments));
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Wraps a function of any arity (including nullary) in a function that accepts exactly 1
|
|
* parameter. Any extraneous parameters will not be passed to the supplied function.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (* -> b) -> (a -> b)
|
|
* @param {Function} fn The function to wrap.
|
|
* @return {Function} A new function wrapping `fn`. The new function is guaranteed to be of
|
|
* arity 1.
|
|
* @example
|
|
*
|
|
* var takesTwoArgs = function(a, b) {
|
|
* return [a, b];
|
|
* };
|
|
* takesTwoArgs.length; //=> 2
|
|
* takesTwoArgs(1, 2); //=> [1, 2]
|
|
*
|
|
* var takesOneArg = R.unary(takesTwoArgs);
|
|
* takesOneArg.length; //=> 1
|
|
* // Only 1 argument is passed to the wrapped function
|
|
* takesOneArg(1, 2); //=> [1, undefined]
|
|
*/
|
|
var unary = _curry1(function unary(fn) {
|
|
return nAry(1, fn);
|
|
});
|
|
|
|
/**
|
|
* Builds a list from a seed value. Accepts an iterator function, which returns either false
|
|
* to stop iteration or an array of length 2 containing the value to add to the resulting
|
|
* list and the seed to be used in the next call to the iterator function.
|
|
*
|
|
* The iterator function receives one argument: *(seed)*.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> [b]) -> * -> [b]
|
|
* @param {Function} fn The iterator function. receives one argument, `seed`, and returns
|
|
* either false to quit iteration or an array of length two to proceed. The element
|
|
* at index 0 of this array will be added to the resulting array, and the element
|
|
* at index 1 will be passed to the next call to `fn`.
|
|
* @param {*} seed The seed value.
|
|
* @return {Array} The final list.
|
|
* @example
|
|
*
|
|
* var f = function(n) { return n > 50 ? false : [-n, n + 10] };
|
|
* R.unfold(f, 10); //=> [-10, -20, -30, -40, -50]
|
|
*/
|
|
var unfold = _curry2(function unfold(fn, seed) {
|
|
var pair = fn(seed);
|
|
var result = [];
|
|
while (pair && pair.length) {
|
|
result[result.length] = pair[0];
|
|
pair = fn(pair[1]);
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Returns a new list containing only one copy of each element in the original list, based
|
|
* upon the value returned by applying the supplied predicate to two list elements. Prefers
|
|
* the first item if two items compare equal based on the predicate.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a, a -> Boolean) -> [a] -> [a]
|
|
* @param {Function} pred A predicate used to test whether two items are equal.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Array} The list of unique items.
|
|
* @example
|
|
*
|
|
* var strEq = function(a, b) { return String(a) === String(b); };
|
|
* R.uniqWith(strEq)([1, '1', 2, 1]); //=> [1, 2]
|
|
* R.uniqWith(strEq)([{}, {}]); //=> [{}]
|
|
* R.uniqWith(strEq)([1, '1', 1]); //=> [1]
|
|
* R.uniqWith(strEq)(['1', 1, 1]); //=> ['1']
|
|
*/
|
|
var uniqWith = _curry2(function uniqWith(pred, list) {
|
|
var idx = 0, len = list.length;
|
|
var result = [], item;
|
|
while (idx < len) {
|
|
item = list[idx];
|
|
if (!_containsWith(pred, item, result)) {
|
|
result[result.length] = item;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Returns a new copy of the array with the element at the
|
|
* provided index replaced with the given value.
|
|
* @see R.adjust
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> a -> [a] -> [a]
|
|
* @param {Number} idx The index to update.
|
|
* @param {*} x The value to exist at the given index of the returned array.
|
|
* @param {Array|Arguments} list The source array-like object to be updated.
|
|
* @return {Array} A copy of `list` with the value at index `idx` replaced with `x`.
|
|
* @example
|
|
*
|
|
* R.update(1, 11, [0, 1, 2]); //=> [0, 11, 2]
|
|
* R.update(1)(11)([0, 1, 2]); //=> [0, 11, 2]
|
|
*/
|
|
var update = _curry3(function (idx, x, list) {
|
|
return adjust(always(x), idx, list);
|
|
});
|
|
|
|
/**
|
|
* Returns a list of all the enumerable own properties of the supplied object.
|
|
* Note that the order of the output array is not guaranteed across
|
|
* different JS platforms.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {k: v} -> [v]
|
|
* @param {Object} obj The object to extract values from
|
|
* @return {Array} An array of the values of the object's own properties.
|
|
* @example
|
|
*
|
|
* R.values({a: 1, b: 2, c: 3}); //=> [1, 2, 3]
|
|
*/
|
|
var values = _curry1(function values(obj) {
|
|
var props = keys(obj);
|
|
var len = props.length;
|
|
var vals = [];
|
|
var idx = 0;
|
|
while (idx < len) {
|
|
vals[idx] = obj[props[idx]];
|
|
idx += 1;
|
|
}
|
|
return vals;
|
|
});
|
|
|
|
/**
|
|
* Returns a list of all the properties, including prototype properties,
|
|
* of the supplied object.
|
|
* Note that the order of the output array is not guaranteed to be
|
|
* consistent across different JS platforms.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {k: v} -> [v]
|
|
* @param {Object} obj The object to extract values from
|
|
* @return {Array} An array of the values of the object's own and prototype properties.
|
|
* @example
|
|
*
|
|
* var F = function() { this.x = 'X'; };
|
|
* F.prototype.y = 'Y';
|
|
* var f = new F();
|
|
* R.valuesIn(f); //=> ['X', 'Y']
|
|
*/
|
|
var valuesIn = _curry1(function valuesIn(obj) {
|
|
var prop, vs = [];
|
|
for (prop in obj) {
|
|
vs[vs.length] = obj[prop];
|
|
}
|
|
return vs;
|
|
});
|
|
|
|
/**
|
|
* Takes a spec object and a test object; returns true if the test satisfies
|
|
* the spec. Each of the spec's own properties must be a predicate function.
|
|
* Each predicate is applied to the value of the corresponding property of
|
|
* the test object. `where` returns true if all the predicates return true,
|
|
* false otherwise.
|
|
*
|
|
* `where` is well suited to declaratively expressing constraints for other
|
|
* functions such as `filter` and `find`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {String: (* -> Boolean)} -> {String: *} -> Boolean
|
|
* @param {Object} spec
|
|
* @param {Object} testObj
|
|
* @return {Boolean}
|
|
* @example
|
|
*
|
|
* // pred :: Object -> Boolean
|
|
* var pred = R.where({
|
|
* a: R.equals('foo'),
|
|
* b: R.complement(R.equals('bar')),
|
|
* x: R.gt(_, 10),
|
|
* y: R.lt(_, 20)
|
|
* });
|
|
*
|
|
* pred({a: 'foo', b: 'xxx', x: 11, y: 19}); //=> true
|
|
* pred({a: 'xxx', b: 'xxx', x: 11, y: 19}); //=> false
|
|
* pred({a: 'foo', b: 'bar', x: 11, y: 19}); //=> false
|
|
* pred({a: 'foo', b: 'xxx', x: 10, y: 19}); //=> false
|
|
* pred({a: 'foo', b: 'xxx', x: 11, y: 20}); //=> false
|
|
*/
|
|
var where = _curry2(function where(spec, testObj) {
|
|
for (var prop in spec) {
|
|
if (_has(prop, spec) && !spec[prop](testObj[prop])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
});
|
|
|
|
/**
|
|
* Creates a new list out of the two supplied by creating each possible
|
|
* pair from the lists.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [b] -> [[a,b]]
|
|
* @param {Array} as The first list.
|
|
* @param {Array} bs The second list.
|
|
* @return {Array} The list made by combining each possible pair from
|
|
* `as` and `bs` into pairs (`[a, b]`).
|
|
* @example
|
|
*
|
|
* R.xprod([1, 2], ['a', 'b']); //=> [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
|
|
*/
|
|
// = xprodWith(prepend); (takes about 3 times as long...)
|
|
var xprod = _curry2(function xprod(a, b) {
|
|
// = xprodWith(prepend); (takes about 3 times as long...)
|
|
var idx = 0;
|
|
var ilen = a.length;
|
|
var j;
|
|
var jlen = b.length;
|
|
var result = [];
|
|
while (idx < ilen) {
|
|
j = 0;
|
|
while (j < jlen) {
|
|
result[result.length] = [
|
|
a[idx],
|
|
b[j]
|
|
];
|
|
j += 1;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Creates a new list out of the two supplied by pairing up
|
|
* equally-positioned items from both lists. The returned list is
|
|
* truncated to the length of the shorter of the two input lists.
|
|
* Note: `zip` is equivalent to `zipWith(function(a, b) { return [a, b] })`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [b] -> [[a,b]]
|
|
* @param {Array} list1 The first array to consider.
|
|
* @param {Array} list2 The second array to consider.
|
|
* @return {Array} The list made by pairing up same-indexed elements of `list1` and `list2`.
|
|
* @example
|
|
*
|
|
* R.zip([1, 2, 3], ['a', 'b', 'c']); //=> [[1, 'a'], [2, 'b'], [3, 'c']]
|
|
*/
|
|
var zip = _curry2(function zip(a, b) {
|
|
var rv = [];
|
|
var idx = 0;
|
|
var len = Math.min(a.length, b.length);
|
|
while (idx < len) {
|
|
rv[idx] = [
|
|
a[idx],
|
|
b[idx]
|
|
];
|
|
idx += 1;
|
|
}
|
|
return rv;
|
|
});
|
|
|
|
/**
|
|
* Creates a new object out of a list of keys and a list of values.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [String] -> [*] -> {String: *}
|
|
* @param {Array} keys The array that will be properties on the output object.
|
|
* @param {Array} values The list of values on the output object.
|
|
* @return {Object} The object made by pairing up same-indexed elements of `keys` and `values`.
|
|
* @example
|
|
*
|
|
* R.zipObj(['a', 'b', 'c'], [1, 2, 3]); //=> {a: 1, b: 2, c: 3}
|
|
*/
|
|
var zipObj = _curry2(function zipObj(keys, values) {
|
|
var idx = 0, len = keys.length, out = {};
|
|
while (idx < len) {
|
|
out[keys[idx]] = values[idx];
|
|
idx += 1;
|
|
}
|
|
return out;
|
|
});
|
|
|
|
/**
|
|
* Creates a new list out of the two supplied by applying the function to
|
|
* each equally-positioned pair in the lists. The returned list is
|
|
* truncated to the length of the shorter of the two input lists.
|
|
*
|
|
* @function
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a,b -> c) -> [a] -> [b] -> [c]
|
|
* @param {Function} fn The function used to combine the two elements into one value.
|
|
* @param {Array} list1 The first array to consider.
|
|
* @param {Array} list2 The second array to consider.
|
|
* @return {Array} The list made by combining same-indexed elements of `list1` and `list2`
|
|
* using `fn`.
|
|
* @example
|
|
*
|
|
* var f = function(x, y) {
|
|
* // ...
|
|
* };
|
|
* R.zipWith(f, [1, 2, 3], ['a', 'b', 'c']);
|
|
* //=> [f(1, 'a'), f(2, 'b'), f(3, 'c')]
|
|
*/
|
|
var zipWith = _curry3(function zipWith(fn, a, b) {
|
|
var rv = [], idx = 0, len = Math.min(a.length, b.length);
|
|
while (idx < len) {
|
|
rv[idx] = fn(a[idx], b[idx]);
|
|
idx += 1;
|
|
}
|
|
return rv;
|
|
});
|
|
|
|
/**
|
|
* A function that always returns `false`. Any passed in parameters are ignored.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig * -> false
|
|
* @see R.always
|
|
* @return {Boolean} false
|
|
* @example
|
|
*
|
|
* R.F(); //=> false
|
|
*/
|
|
var F = always(false);
|
|
|
|
/**
|
|
* A function that always returns `true`. Any passed in parameters are ignored.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig * -> true
|
|
* @see R.always
|
|
* @return {Boolean} `true`.
|
|
* @example
|
|
*
|
|
* R.T(); //=> true
|
|
*/
|
|
var T = always(true);
|
|
|
|
var _append = function _append(el, list) {
|
|
return _concat(list, [el]);
|
|
};
|
|
|
|
var _assocPath = function _assocPath(path, val, obj) {
|
|
switch (path.length) {
|
|
case 0:
|
|
return obj;
|
|
case 1:
|
|
return _assoc(path[0], val, obj);
|
|
default:
|
|
return _assoc(path[0], _assocPath(_slice(path, 1), val, Object(obj[path[0]])), obj);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Copies an object.
|
|
*
|
|
* @private
|
|
* @param {*} value The value to be copied
|
|
* @param {Array} refFrom Array containing the source references
|
|
* @param {Array} refTo Array containing the copied source references
|
|
* @return {*} The copied value.
|
|
*/
|
|
var _baseCopy = function _baseCopy(value, refFrom, refTo) {
|
|
var copy = function copy(copiedValue) {
|
|
var len = refFrom.length;
|
|
var idx = 0;
|
|
while (idx < len) {
|
|
if (value === refFrom[idx]) {
|
|
return refTo[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
refFrom[idx + 1] = value;
|
|
refTo[idx + 1] = copiedValue;
|
|
for (var key in value) {
|
|
copiedValue[key] = _baseCopy(value[key], refFrom, refTo);
|
|
}
|
|
return copiedValue;
|
|
};
|
|
switch (type(value)) {
|
|
case 'Object':
|
|
return copy({});
|
|
case 'Array':
|
|
return copy([]);
|
|
case 'Date':
|
|
return new Date(value);
|
|
case 'RegExp':
|
|
return _cloneRegExp(value);
|
|
default:
|
|
return value;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Similar to hasMethod, this checks whether a function has a [methodname]
|
|
* function. If it isn't an array it will execute that function otherwise it will
|
|
* default to the ramda implementation.
|
|
*
|
|
* @private
|
|
* @param {Function} fn ramda implemtation
|
|
* @param {String} methodname property to check for a custom implementation
|
|
* @return {Object} Whatever the return value of the method is.
|
|
*/
|
|
var _checkForMethod = function _checkForMethod(methodname, fn) {
|
|
return function () {
|
|
var length = arguments.length;
|
|
if (length === 0) {
|
|
return fn();
|
|
}
|
|
var obj = arguments[length - 1];
|
|
return _isArray(obj) || typeof obj[methodname] !== 'function' ? fn.apply(this, arguments) : obj[methodname].apply(obj, _slice(arguments, 0, length - 1));
|
|
};
|
|
};
|
|
|
|
var _composeL = function _composeL(innerLens, outerLens) {
|
|
return lens(_compose(innerLens, outerLens), function (x, source) {
|
|
var newInnerValue = innerLens.set(x, outerLens(source));
|
|
return outerLens.set(newInnerValue, source);
|
|
});
|
|
};
|
|
|
|
/**
|
|
* A right-associative two-argument composition function like `_compose`
|
|
* but with automatic handling of promises (or, more precisely,
|
|
* "thenables"). This function is used to construct a more general
|
|
* `composeP` function, which accepts any number of arguments.
|
|
*
|
|
* @private
|
|
* @category Function
|
|
* @param {Function} f A function.
|
|
* @param {Function} g A function.
|
|
* @return {Function} A new function that is the equivalent of `f(g(x))`.
|
|
* @example
|
|
*
|
|
* var Q = require('q');
|
|
* var double = function(x) { return x * 2; };
|
|
* var squareAsync = function(x) { return Q.when(x * x); };
|
|
* var squareAsyncThenDouble = _composeP(double, squareAsync);
|
|
*
|
|
* squareAsyncThenDouble(5)
|
|
* .then(function(result) {
|
|
* // the result is now 50.
|
|
* });
|
|
*/
|
|
var _composeP = function _composeP(f, g) {
|
|
return function () {
|
|
var context = this;
|
|
var value = g.apply(this, arguments);
|
|
if (_isThenable(value)) {
|
|
return value.then(function (result) {
|
|
return f.call(context, result);
|
|
});
|
|
} else {
|
|
return f.call(this, value);
|
|
}
|
|
};
|
|
};
|
|
|
|
/*
|
|
* Returns a function that makes a multi-argument version of compose from
|
|
* either _compose or _composeP.
|
|
*/
|
|
var _createComposer = function _createComposer(composeFunction) {
|
|
return function () {
|
|
var fn = arguments[arguments.length - 1];
|
|
var length = fn.length;
|
|
var idx = arguments.length - 2;
|
|
while (idx >= 0) {
|
|
fn = composeFunction(arguments[idx], fn);
|
|
idx -= 1;
|
|
}
|
|
return arity(length, fn);
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Create a function which takes a list
|
|
* and determines the winning value by a comparator. Used internally
|
|
* by `R.max` and `R.min`
|
|
*
|
|
* @private
|
|
* @param {Function} compatator a function to compare two items
|
|
* @param {*} intialVal, default value if nothing else wins
|
|
* @category Math
|
|
* @return {Function}
|
|
*/
|
|
var _createMaxMin = function _createMaxMin(comparator, initialVal) {
|
|
return _curry1(function (list) {
|
|
var idx = 0, winner = initialVal, computed;
|
|
while (idx < list.length) {
|
|
computed = +list[idx];
|
|
if (comparator(computed, winner)) {
|
|
winner = computed;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return winner;
|
|
});
|
|
};
|
|
|
|
var _createPartialApplicator = function _createPartialApplicator(concat) {
|
|
return function (fn) {
|
|
var args = _slice(arguments, 1);
|
|
return arity(Math.max(0, fn.length - args.length), function () {
|
|
return fn.apply(this, concat(args, arguments));
|
|
});
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Internal curryN function.
|
|
*
|
|
* @private
|
|
* @category Function
|
|
* @param {Number} length The arity of the curried function.
|
|
* @return {array} An array of arguments received thus far.
|
|
* @param {Function} fn The function to curry.
|
|
*/
|
|
var _curryN = function _curryN(length, received, fn) {
|
|
return function () {
|
|
var combined = [];
|
|
var argsIdx = 0;
|
|
var left = length;
|
|
var combinedIdx = 0;
|
|
while (combinedIdx < received.length || argsIdx < arguments.length) {
|
|
var result;
|
|
if (combinedIdx < received.length && (received[combinedIdx] == null || received[combinedIdx]['@@functional/placeholder'] !== true || argsIdx >= arguments.length)) {
|
|
result = received[combinedIdx];
|
|
} else {
|
|
result = arguments[argsIdx];
|
|
argsIdx += 1;
|
|
}
|
|
combined[combinedIdx] = result;
|
|
if (result == null || result['@@functional/placeholder'] !== true) {
|
|
left -= 1;
|
|
}
|
|
combinedIdx += 1;
|
|
}
|
|
return left <= 0 ? fn.apply(this, combined) : arity(left, _curryN(length, combined, fn));
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Returns a function that dispatches with different strategies based on the
|
|
* object in list position (last argument). If it is an array, executes [fn].
|
|
* Otherwise, if it has a function with [methodname], it will execute that
|
|
* function (functor case). Otherwise, if it is a transformer, uses transducer
|
|
* [xf] to return a new transformer (transducer case). Otherwise, it will
|
|
* default to executing [fn].
|
|
*
|
|
* @private
|
|
* @param {String} methodname property to check for a custom implementation
|
|
* @param {Function} xf transducer to initialize if object is transformer
|
|
* @param {Function} fn default ramda implementation
|
|
* @return {Function} A function that dispatches on object in list position
|
|
*/
|
|
var _dispatchable = function _dispatchable(methodname, xf, fn) {
|
|
return function () {
|
|
var length = arguments.length;
|
|
if (length === 0) {
|
|
return fn();
|
|
}
|
|
var obj = arguments[length - 1];
|
|
if (!_isArray(obj)) {
|
|
var args = _slice(arguments, 0, length - 1);
|
|
if (typeof obj[methodname] === 'function') {
|
|
return obj[methodname].apply(obj, args);
|
|
}
|
|
if (_isTransformer(obj)) {
|
|
var transducer = xf.apply(null, args);
|
|
return transducer(obj);
|
|
}
|
|
}
|
|
return fn.apply(this, arguments);
|
|
};
|
|
};
|
|
|
|
var _dissocPath = function _dissocPath(path, obj) {
|
|
switch (path.length) {
|
|
case 0:
|
|
return obj;
|
|
case 1:
|
|
return _dissoc(path[0], obj);
|
|
default:
|
|
var head = path[0];
|
|
var tail = _slice(path, 1);
|
|
return obj[head] == null ? obj : _assoc(head, _dissocPath(tail, obj[head]), obj);
|
|
}
|
|
};
|
|
|
|
// The algorithm used to handle cyclic structures is
|
|
// inspired by underscore's isEqual
|
|
// RegExp equality algorithm: http://stackoverflow.com/a/10776635
|
|
var _equals = function _eqDeep(a, b, stackA, stackB) {
|
|
var typeA = type(a);
|
|
if (typeA !== type(b)) {
|
|
return false;
|
|
}
|
|
if (typeA === 'Boolean' || typeA === 'Number' || typeA === 'String') {
|
|
return typeof a === 'object' ? typeof b === 'object' && identical(a.valueOf(), b.valueOf()) : identical(a, b);
|
|
}
|
|
if (identical(a, b)) {
|
|
return true;
|
|
}
|
|
if (typeA === 'RegExp') {
|
|
// RegExp equality algorithm: http://stackoverflow.com/a/10776635
|
|
return a.source === b.source && a.global === b.global && a.ignoreCase === b.ignoreCase && a.multiline === b.multiline && a.sticky === b.sticky && a.unicode === b.unicode;
|
|
}
|
|
if (Object(a) === a) {
|
|
if (typeA === 'Date' && a.getTime() !== b.getTime()) {
|
|
return false;
|
|
}
|
|
var keysA = keys(a);
|
|
if (keysA.length !== keys(b).length) {
|
|
return false;
|
|
}
|
|
var idx = stackA.length - 1;
|
|
while (idx >= 0) {
|
|
if (stackA[idx] === a) {
|
|
return stackB[idx] === b;
|
|
}
|
|
idx -= 1;
|
|
}
|
|
stackA[stackA.length] = a;
|
|
stackB[stackB.length] = b;
|
|
idx = keysA.length - 1;
|
|
while (idx >= 0) {
|
|
var key = keysA[idx];
|
|
if (!_has(key, b) || !_eqDeep(b[key], a[key], stackA, stackB)) {
|
|
return false;
|
|
}
|
|
idx -= 1;
|
|
}
|
|
stackA.pop();
|
|
stackB.pop();
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Assigns own enumerable properties of the other object to the destination
|
|
* object preferring items in other.
|
|
*
|
|
* @private
|
|
* @memberOf R
|
|
* @category Object
|
|
* @param {Object} destination The destination object.
|
|
* @param {Object} other The other object to merge with destination.
|
|
* @return {Object} The destination object.
|
|
* @example
|
|
*
|
|
* _extend({ 'name': 'fred', 'age': 10 }, { 'age': 40 });
|
|
* //=> { 'name': 'fred', 'age': 40 }
|
|
*/
|
|
var _extend = function _extend(destination, other) {
|
|
var props = keys(other);
|
|
var idx = 0, length = props.length;
|
|
while (idx < length) {
|
|
destination[props[idx]] = other[props[idx]];
|
|
idx += 1;
|
|
}
|
|
return destination;
|
|
};
|
|
|
|
/**
|
|
* Private function that determines whether or not a provided object has a given method.
|
|
* Does not ignore methods stored on the object's prototype chain. Used for dynamically
|
|
* dispatching Ramda methods to non-Array objects.
|
|
*
|
|
* @private
|
|
* @param {String} methodName The name of the method to check for.
|
|
* @param {Object} obj The object to test.
|
|
* @return {Boolean} `true` has a given method, `false` otherwise.
|
|
* @example
|
|
*
|
|
* var person = { name: 'John' };
|
|
* person.shout = function() { alert(this.name); };
|
|
*
|
|
* _hasMethod('shout', person); //=> true
|
|
* _hasMethod('foo', person); //=> false
|
|
*/
|
|
var _hasMethod = function _hasMethod(methodName, obj) {
|
|
return obj != null && !_isArray(obj) && typeof obj[methodName] === 'function';
|
|
};
|
|
|
|
/**
|
|
* `_makeFlat` is a helper function that returns a one-level or fully recursive function
|
|
* based on the flag passed in.
|
|
*
|
|
* @private
|
|
*/
|
|
var _makeFlat = function _makeFlat(recursive) {
|
|
return function flatt(list) {
|
|
var value, result = [], idx = 0, j, ilen = list.length, jlen;
|
|
while (idx < ilen) {
|
|
if (isArrayLike(list[idx])) {
|
|
value = recursive ? flatt(list[idx]) : list[idx];
|
|
j = 0;
|
|
jlen = value.length;
|
|
while (j < jlen) {
|
|
result[result.length] = value[j];
|
|
j += 1;
|
|
}
|
|
} else {
|
|
result[result.length] = list[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
return result;
|
|
};
|
|
};
|
|
|
|
var _reduce = function () {
|
|
function _arrayReduce(xf, acc, list) {
|
|
var idx = 0, len = list.length;
|
|
while (idx < len) {
|
|
acc = xf['@@transducer/step'](acc, list[idx]);
|
|
if (acc && acc['@@transducer/reduced']) {
|
|
acc = acc['@@transducer/value'];
|
|
break;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return xf['@@transducer/result'](acc);
|
|
}
|
|
function _iterableReduce(xf, acc, iter) {
|
|
var step = iter.next();
|
|
while (!step.done) {
|
|
acc = xf['@@transducer/step'](acc, step.value);
|
|
if (acc && acc['@@transducer/reduced']) {
|
|
acc = acc['@@transducer/value'];
|
|
break;
|
|
}
|
|
step = iter.next();
|
|
}
|
|
return xf['@@transducer/result'](acc);
|
|
}
|
|
function _methodReduce(xf, acc, obj) {
|
|
return xf['@@transducer/result'](obj.reduce(bind(xf['@@transducer/step'], xf), acc));
|
|
}
|
|
var symIterator = typeof Symbol !== 'undefined' ? Symbol.iterator : '@@iterator';
|
|
return function _reduce(fn, acc, list) {
|
|
if (typeof fn === 'function') {
|
|
fn = _xwrap(fn);
|
|
}
|
|
if (isArrayLike(list)) {
|
|
return _arrayReduce(fn, acc, list);
|
|
}
|
|
if (typeof list.reduce === 'function') {
|
|
return _methodReduce(fn, acc, list);
|
|
}
|
|
if (list[symIterator] != null) {
|
|
return _iterableReduce(fn, acc, list[symIterator]());
|
|
}
|
|
if (typeof list.next === 'function') {
|
|
return _iterableReduce(fn, acc, list);
|
|
}
|
|
throw new TypeError('reduce: list must be array or iterable');
|
|
};
|
|
}();
|
|
|
|
var _xall = function () {
|
|
function XAll(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
this.all = true;
|
|
}
|
|
XAll.prototype['@@transducer/init'] = _xfBase.init;
|
|
XAll.prototype['@@transducer/result'] = function (result) {
|
|
if (this.all) {
|
|
result = this.xf['@@transducer/step'](result, true);
|
|
}
|
|
return this.xf['@@transducer/result'](result);
|
|
};
|
|
XAll.prototype['@@transducer/step'] = function (result, input) {
|
|
if (!this.f(input)) {
|
|
this.all = false;
|
|
result = _reduced(this.xf['@@transducer/step'](result, false));
|
|
}
|
|
return result;
|
|
};
|
|
return _curry2(function _xall(f, xf) {
|
|
return new XAll(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xany = function () {
|
|
function XAny(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
this.any = false;
|
|
}
|
|
XAny.prototype['@@transducer/init'] = _xfBase.init;
|
|
XAny.prototype['@@transducer/result'] = function (result) {
|
|
if (!this.any) {
|
|
result = this.xf['@@transducer/step'](result, false);
|
|
}
|
|
return this.xf['@@transducer/result'](result);
|
|
};
|
|
XAny.prototype['@@transducer/step'] = function (result, input) {
|
|
if (this.f(input)) {
|
|
this.any = true;
|
|
result = _reduced(this.xf['@@transducer/step'](result, true));
|
|
}
|
|
return result;
|
|
};
|
|
return _curry2(function _xany(f, xf) {
|
|
return new XAny(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xdrop = function () {
|
|
function XDrop(n, xf) {
|
|
this.xf = xf;
|
|
this.n = n;
|
|
}
|
|
XDrop.prototype['@@transducer/init'] = _xfBase.init;
|
|
XDrop.prototype['@@transducer/result'] = _xfBase.result;
|
|
XDrop.prototype.step = function (result, input) {
|
|
if (this.n > 0) {
|
|
this.n -= 1;
|
|
return result;
|
|
}
|
|
return this.xf['@@transducer/step'](result, input);
|
|
};
|
|
return _curry2(function _xdrop(n, xf) {
|
|
return new XDrop(n, xf);
|
|
});
|
|
}();
|
|
|
|
var _xdropWhile = function () {
|
|
function XDropWhile(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
}
|
|
XDropWhile.prototype['@@transducer/init'] = _xfBase.init;
|
|
XDropWhile.prototype['@@transducer/result'] = _xfBase.result;
|
|
XDropWhile.prototype['@@transducer/step'] = function (result, input) {
|
|
if (this.f) {
|
|
if (this.f(input)) {
|
|
return result;
|
|
}
|
|
this.f = null;
|
|
}
|
|
return this.xf['@@transducer/step'](result, input);
|
|
};
|
|
return _curry2(function _xdropWhile(f, xf) {
|
|
return new XDropWhile(f, xf);
|
|
});
|
|
}();
|
|
|
|
var _xgroupBy = function () {
|
|
function XGroupBy(f, xf) {
|
|
this.xf = xf;
|
|
this.f = f;
|
|
this.inputs = {};
|
|
}
|
|
XGroupBy.prototype['@@transducer/init'] = _xfBase.init;
|
|
XGroupBy.prototype['@@transducer/result'] = function (result) {
|
|
var key;
|
|
for (key in this.inputs) {
|
|
if (_has(key, this.inputs)) {
|
|
result = this.xf['@@transducer/step'](result, this.inputs[key]);
|
|
if (result['@@transducer/reduced']) {
|
|
result = result['@@transducer/value'];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return this.xf['@@transducer/result'](result);
|
|
};
|
|
XGroupBy.prototype['@@transducer/step'] = function (result, input) {
|
|
var key = this.f(input);
|
|
this.inputs[key] = this.inputs[key] || [
|
|
key,
|
|
[]
|
|
];
|
|
this.inputs[key][1] = _append(input, this.inputs[key][1]);
|
|
return result;
|
|
};
|
|
return _curry2(function _xgroupBy(f, xf) {
|
|
return new XGroupBy(f, xf);
|
|
});
|
|
}();
|
|
|
|
/**
|
|
* Returns `true` if all elements of the list match the predicate, `false` if there are any
|
|
* that don't.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> Boolean
|
|
* @param {Function} fn The predicate function.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Boolean} `true` if the predicate is satisfied by every element, `false`
|
|
* otherwise.
|
|
* @example
|
|
*
|
|
* var lessThan2 = R.flip(R.lt)(2);
|
|
* var lessThan3 = R.flip(R.lt)(3);
|
|
* R.all(lessThan2)([1, 2]); //=> false
|
|
* R.all(lessThan3)([1, 2]); //=> true
|
|
*/
|
|
var all = _curry2(_dispatchable('all', _xall, _all));
|
|
|
|
/**
|
|
* A function that returns the first argument if it's falsy otherwise the second
|
|
* argument. Note that this is NOT short-circuited, meaning that if expressions
|
|
* are passed they are both evaluated.
|
|
*
|
|
* Dispatches to the `and` method of the first argument if applicable.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig * -> * -> *
|
|
* @param {*} a any value
|
|
* @param {*} b any other value
|
|
* @return {*} the first argument if falsy otherwise the second argument.
|
|
* @example
|
|
*
|
|
* R.and(false, true); //=> false
|
|
* R.and(0, []); //=> 0
|
|
* R.and(null, ''); => null
|
|
*/
|
|
var and = _curry2(function and(a, b) {
|
|
return _hasMethod('and', a) ? a.and(b) : a && b;
|
|
});
|
|
|
|
/**
|
|
* Returns `true` if at least one of elements of the list match the predicate, `false`
|
|
* otherwise.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> Boolean
|
|
* @param {Function} fn The predicate function.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Boolean} `true` if the predicate is satisfied by at least one element, `false`
|
|
* otherwise.
|
|
* @example
|
|
*
|
|
* var lessThan0 = R.flip(R.lt)(0);
|
|
* var lessThan2 = R.flip(R.lt)(2);
|
|
* R.any(lessThan0)([1, 2]); //=> false
|
|
* R.any(lessThan2)([1, 2]); //=> true
|
|
*/
|
|
var any = _curry2(_dispatchable('any', _xany, _any));
|
|
|
|
/**
|
|
* Returns a new list containing the contents of the given list, followed by the given
|
|
* element.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig a -> [a] -> [a]
|
|
* @param {*} el The element to add to the end of the new list.
|
|
* @param {Array} list The list whose contents will be added to the beginning of the output
|
|
* list.
|
|
* @return {Array} A new list containing the contents of the old list followed by `el`.
|
|
* @example
|
|
*
|
|
* R.append('tests', ['write', 'more']); //=> ['write', 'more', 'tests']
|
|
* R.append('tests', []); //=> ['tests']
|
|
* R.append(['tests'], ['write', 'more']); //=> ['write', 'more', ['tests']]
|
|
*/
|
|
var append = _curry2(_append);
|
|
|
|
/**
|
|
* Makes a shallow clone of an object, setting or overriding the nodes
|
|
* required to create the given path, and placing the specific value at the
|
|
* tail end of that path. Note that this copies and flattens prototype
|
|
* properties onto the new object as well. All non-primitive properties
|
|
* are copied by reference.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig [String] -> a -> {k: v} -> {k: v}
|
|
* @param {Array} path the path to set
|
|
* @param {*} val the new value
|
|
* @param {Object} obj the object to clone
|
|
* @return {Object} a new object similar to the original except along the specified path.
|
|
* @example
|
|
*
|
|
* R.assocPath(['a', 'b', 'c'], 42, {a: {b: {c: 0}}}); //=> {a: {b: {c: 42}}}
|
|
*/
|
|
var assocPath = _curry3(_assocPath);
|
|
|
|
/**
|
|
* Wraps a function of any arity (including nullary) in a function that accepts exactly 2
|
|
* parameters. Any extraneous parameters will not be passed to the supplied function.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (* -> c) -> (a, b -> c)
|
|
* @param {Function} fn The function to wrap.
|
|
* @return {Function} A new function wrapping `fn`. The new function is guaranteed to be of
|
|
* arity 2.
|
|
* @example
|
|
*
|
|
* var takesThreeArgs = function(a, b, c) {
|
|
* return [a, b, c];
|
|
* };
|
|
* takesThreeArgs.length; //=> 3
|
|
* takesThreeArgs(1, 2, 3); //=> [1, 2, 3]
|
|
*
|
|
* var takesTwoArgs = R.binary(takesThreeArgs);
|
|
* takesTwoArgs.length; //=> 2
|
|
* // Only 2 arguments are passed to the wrapped function
|
|
* takesTwoArgs(1, 2, 3); //=> [1, 2, undefined]
|
|
*/
|
|
var binary = _curry1(function binary(fn) {
|
|
return nAry(2, fn);
|
|
});
|
|
|
|
/**
|
|
* Creates a deep copy of the value which may contain (nested) `Array`s and
|
|
* `Object`s, `Number`s, `String`s, `Boolean`s and `Date`s. `Function`s are
|
|
* not copied, but assigned by their reference.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {*} -> {*}
|
|
* @param {*} value The object or array to clone
|
|
* @return {*} A new object or array.
|
|
* @example
|
|
*
|
|
* var objects = [{}, {}, {}];
|
|
* var objectsClone = R.clone(objects);
|
|
* objects[0] === objectsClone[0]; //=> false
|
|
*/
|
|
var clone = _curry1(function clone(value) {
|
|
return _baseCopy(value, [], []);
|
|
});
|
|
|
|
/**
|
|
* Creates a new function that runs each of the functions supplied as parameters in turn,
|
|
* passing the return value of each function invocation to the next function invocation,
|
|
* beginning with whatever arguments were passed to the initial invocation.
|
|
*
|
|
* Note that `compose` is a right-associative function, which means the functions provided
|
|
* will be invoked in order from right to left. In the example `var h = compose(f, g)`,
|
|
* the function `h` is equivalent to `f( g(x) )`, where `x` represents the arguments
|
|
* originally passed to `h`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig ((y -> z), (x -> y), ..., (b -> c), (a... -> b)) -> (a... -> z)
|
|
* @param {...Function} functions A variable number of functions.
|
|
* @return {Function} A new function which represents the result of calling each of the
|
|
* input `functions`, passing the result of each function call to the next, from
|
|
* right to left.
|
|
* @example
|
|
*
|
|
* var triple = function(x) { return x * 3; };
|
|
* var double = function(x) { return x * 2; };
|
|
* var square = function(x) { return x * x; };
|
|
* var squareThenDoubleThenTriple = R.compose(triple, double, square);
|
|
*
|
|
* //≅ triple(double(square(5)))
|
|
* squareThenDoubleThenTriple(5); //=> 150
|
|
*/
|
|
var compose = _createComposer(_compose);
|
|
|
|
/**
|
|
* Creates a new lens that allows getting and setting values of nested properties, by
|
|
* following each given lens in succession.
|
|
*
|
|
* Note that `composeL` is a right-associative function, which means the lenses provided
|
|
* will be invoked in order from right to left.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @see R.lens
|
|
* @sig ((y -> z), (x -> y), ..., (b -> c), (a -> b)) -> (a -> z)
|
|
* @param {...Function} lenses A variable number of lenses.
|
|
* @return {Function} A new lens which represents the result of calling each of the
|
|
* input `lenses`, passing the result of each getter/setter as the source
|
|
* to the next, from right to left.
|
|
* @example
|
|
*
|
|
* var headLens = R.lensIndex(0);
|
|
* var secondLens = R.lensIndex(1);
|
|
* var xLens = R.lensProp('x');
|
|
* var secondOfXOfHeadLens = R.composeL(secondLens, xLens, headLens);
|
|
*
|
|
* var source = [{x: [0, 1], y: [2, 3]}, {x: [4, 5], y: [6, 7]}];
|
|
* secondOfXOfHeadLens(source); //=> 1
|
|
* secondOfXOfHeadLens.set(123, source); //=> [{x: [0, 123], y: [2, 3]}, {x: [4, 5], y: [6, 7]}]
|
|
*/
|
|
var composeL = function () {
|
|
var fn = arguments[arguments.length - 1];
|
|
var idx = arguments.length - 2;
|
|
while (idx >= 0) {
|
|
fn = _composeL(arguments[idx], fn);
|
|
idx -= 1;
|
|
}
|
|
return fn;
|
|
};
|
|
|
|
/**
|
|
* Similar to `compose` but with automatic handling of promises (or, more
|
|
* precisely, "thenables"). The behavior is identical to that of
|
|
* compose() if all composed functions return something other than
|
|
* promises (i.e., objects with a .then() method). If one of the function
|
|
* returns a promise, however, then the next function in the composition
|
|
* is called asynchronously, in the success callback of the promise, using
|
|
* the resolved value as an input. Note that `composeP` is a right-
|
|
* associative function, just like `compose`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig ((y -> z), (x -> y), ..., (b -> c), (a... -> b)) -> (a... -> z)
|
|
* @param {...Function} functions A variable number of functions.
|
|
* @return {Function} A new function which represents the result of calling each of the
|
|
* input `functions`, passing either the returned result or the asynchronously
|
|
* resolved value) of each function call to the next, from right to left.
|
|
* @example
|
|
*
|
|
* var Q = require('q');
|
|
* var triple = function(x) { return x * 3; };
|
|
* var double = function(x) { return x * 2; };
|
|
* var squareAsync = function(x) { return Q.when(x * x); };
|
|
* var squareAsyncThenDoubleThenTriple = R.composeP(triple, double, squareAsync);
|
|
*
|
|
* //≅ squareAsync(5).then(function(x) { return triple(double(x)) };
|
|
* squareAsyncThenDoubleThenTriple(5)
|
|
* .then(function(result) {
|
|
* // result is 150
|
|
* });
|
|
*/
|
|
var composeP = _createComposer(_composeP);
|
|
|
|
/**
|
|
* Returns a new list consisting of the elements of the first list followed by the elements
|
|
* of the second.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [a] -> [a]
|
|
* @param {Array} list1 The first list to merge.
|
|
* @param {Array} list2 The second set to merge.
|
|
* @return {Array} A new array consisting of the contents of `list1` followed by the
|
|
* contents of `list2`. If, instead of an Array for `list1`, you pass an
|
|
* object with a `concat` method on it, `concat` will call `list1.concat`
|
|
* and pass it the value of `list2`.
|
|
*
|
|
* @example
|
|
*
|
|
* R.concat([], []); //=> []
|
|
* R.concat([4, 5, 6], [1, 2, 3]); //=> [4, 5, 6, 1, 2, 3]
|
|
* R.concat('ABC', 'DEF'); // 'ABCDEF'
|
|
*/
|
|
var concat = _curry2(function (set1, set2) {
|
|
if (_isArray(set2)) {
|
|
return _concat(set1, set2);
|
|
} else if (_hasMethod('concat', set1)) {
|
|
return set1.concat(set2);
|
|
} else {
|
|
throw new TypeError('can\'t concat ' + typeof set1);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Returns a curried equivalent of the provided function, with the
|
|
* specified arity. The curried function has two unusual capabilities.
|
|
* First, its arguments needn't be provided one at a time. If `g` is
|
|
* `R.curryN(3, f)`, the following are equivalent:
|
|
*
|
|
* - `g(1)(2)(3)`
|
|
* - `g(1)(2, 3)`
|
|
* - `g(1, 2)(3)`
|
|
* - `g(1, 2, 3)`
|
|
*
|
|
* Secondly, the special placeholder value `R.__` may be used to specify
|
|
* "gaps", allowing partial application of any combination of arguments,
|
|
* regardless of their positions. If `g` is as above and `_` is `R.__`,
|
|
* the following are equivalent:
|
|
*
|
|
* - `g(1, 2, 3)`
|
|
* - `g(_, 2, 3)(1)`
|
|
* - `g(_, _, 3)(1)(2)`
|
|
* - `g(_, _, 3)(1, 2)`
|
|
* - `g(_, 2)(1)(3)`
|
|
* - `g(_, 2)(1, 3)`
|
|
* - `g(_, 2)(_, 3)(1)`
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig Number -> (* -> a) -> (* -> a)
|
|
* @param {Number} length The arity for the returned function.
|
|
* @param {Function} fn The function to curry.
|
|
* @return {Function} A new, curried function.
|
|
* @see R.curry
|
|
* @example
|
|
*
|
|
* var addFourNumbers = function() {
|
|
* return R.sum([].slice.call(arguments, 0, 4));
|
|
* };
|
|
*
|
|
* var curriedAddFourNumbers = R.curryN(4, addFourNumbers);
|
|
* var f = curriedAddFourNumbers(1, 2);
|
|
* var g = f(3);
|
|
* g(4); //=> 10
|
|
*/
|
|
var curryN = _curry2(function curryN(length, fn) {
|
|
return arity(length, _curryN(length, [], fn));
|
|
});
|
|
|
|
/**
|
|
* Makes a shallow clone of an object, omitting the property at the
|
|
* given path. Note that this copies and flattens prototype properties
|
|
* onto the new object as well. All non-primitive properties are copied
|
|
* by reference.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig [String] -> {k: v} -> {k: v}
|
|
* @param {Array} path the path to set
|
|
* @param {Object} obj the object to clone
|
|
* @return {Object} a new object without the property at path
|
|
* @example
|
|
*
|
|
* R.dissocPath(['a', 'b', 'c'], {a: {b: {c: 42}}}); //=> {a: {b: {}}}
|
|
*/
|
|
var dissocPath = _curry2(_dissocPath);
|
|
|
|
/**
|
|
* Returns a new list containing the last `n` elements of a given list, passing each value
|
|
* to the supplied predicate function, skipping elements while the predicate function returns
|
|
* `true`. The predicate function is passed one argument: *(value)*.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> [a]
|
|
* @param {Function} fn The function called per iteration.
|
|
* @param {Array} list The collection to iterate over.
|
|
* @return {Array} A new array.
|
|
* @example
|
|
*
|
|
* var lteTwo = function(x) {
|
|
* return x <= 2;
|
|
* };
|
|
*
|
|
* R.dropWhile(lteTwo, [1, 2, 3, 4, 3, 2, 1]); //=> [3, 4, 3, 2, 1]
|
|
*/
|
|
var dropWhile = _curry2(_dispatchable('dropWhile', _xdropWhile, function dropWhile(pred, list) {
|
|
var idx = 0, len = list.length;
|
|
while (idx < len && pred(list[idx])) {
|
|
idx += 1;
|
|
}
|
|
return _slice(list, idx);
|
|
}));
|
|
|
|
/**
|
|
* `empty` returns an empty list for any argument, except when the argument satisfies the
|
|
* Fantasy-land Monoid spec. In that case, this function will return the result of invoking
|
|
* `empty` on that Monoid.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig * -> []
|
|
* @return {Array} An empty array.
|
|
* @example
|
|
*
|
|
* R.empty([1,2,3,4,5]); //=> []
|
|
*/
|
|
var empty = _curry1(function empty(x) {
|
|
return _hasMethod('empty', x) ? x.empty() : [];
|
|
});
|
|
|
|
/**
|
|
* Returns `true` if its arguments are equivalent, `false` otherwise.
|
|
* Dispatches to an `equals` method if present. Handles cyclical data
|
|
* structures.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig a -> b -> Boolean
|
|
* @param {*} a
|
|
* @param {*} b
|
|
* @return {Boolean}
|
|
* @example
|
|
*
|
|
* R.equals(1, 1); //=> true
|
|
* R.equals(1, '1'); //=> false
|
|
* R.equals([1, 2, 3], [1, 2, 3]); //=> true
|
|
*
|
|
* var a = {}; a.v = a;
|
|
* var b = {}; b.v = b;
|
|
* R.equals(a, b); //=> true
|
|
*/
|
|
var equals = _curry2(function equals(a, b) {
|
|
return _hasMethod('equals', a) ? a.equals(b) : _hasMethod('equals', b) ? b.equals(a) : _equals(a, b, [], []);
|
|
});
|
|
|
|
/**
|
|
* Returns a new list containing only those items that match a given predicate function.
|
|
* The predicate function is passed one argument: *(value)*.
|
|
*
|
|
* Note that `R.filter` does not skip deleted or unassigned indices, unlike the native
|
|
* `Array.prototype.filter` method. For more details on this behavior, see:
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter#Description
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> [a]
|
|
* @param {Function} fn The function called per iteration.
|
|
* @param {Array} list The collection to iterate over.
|
|
* @return {Array} The new filtered array.
|
|
* @example
|
|
*
|
|
* var isEven = function(n) {
|
|
* return n % 2 === 0;
|
|
* };
|
|
* R.filter(isEven, [1, 2, 3, 4]); //=> [2, 4]
|
|
*/
|
|
var filter = _curry2(_dispatchable('filter', _xfilter, _filter));
|
|
|
|
/**
|
|
* Returns the first element of the list which matches the predicate, or `undefined` if no
|
|
* element matches.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> a | undefined
|
|
* @param {Function} fn The predicate function used to determine if the element is the
|
|
* desired one.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Object} The element found, or `undefined`.
|
|
* @example
|
|
*
|
|
* var xs = [{a: 1}, {a: 2}, {a: 3}];
|
|
* R.find(R.propEq('a', 2))(xs); //=> {a: 2}
|
|
* R.find(R.propEq('a', 4))(xs); //=> undefined
|
|
*/
|
|
var find = _curry2(_dispatchable('find', _xfind, function find(fn, list) {
|
|
var idx = 0;
|
|
var len = list.length;
|
|
while (idx < len) {
|
|
if (fn(list[idx])) {
|
|
return list[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
}));
|
|
|
|
/**
|
|
* Returns the index of the first element of the list which matches the predicate, or `-1`
|
|
* if no element matches.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> Number
|
|
* @param {Function} fn The predicate function used to determine if the element is the
|
|
* desired one.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Number} The index of the element found, or `-1`.
|
|
* @example
|
|
*
|
|
* var xs = [{a: 1}, {a: 2}, {a: 3}];
|
|
* R.findIndex(R.propEq('a', 2))(xs); //=> 1
|
|
* R.findIndex(R.propEq('a', 4))(xs); //=> -1
|
|
*/
|
|
var findIndex = _curry2(_dispatchable('findIndex', _xfindIndex, function findIndex(fn, list) {
|
|
var idx = 0;
|
|
var len = list.length;
|
|
while (idx < len) {
|
|
if (fn(list[idx])) {
|
|
return idx;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return -1;
|
|
}));
|
|
|
|
/**
|
|
* Returns the last element of the list which matches the predicate, or `undefined` if no
|
|
* element matches.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> a | undefined
|
|
* @param {Function} fn The predicate function used to determine if the element is the
|
|
* desired one.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Object} The element found, or `undefined`.
|
|
* @example
|
|
*
|
|
* var xs = [{a: 1, b: 0}, {a:1, b: 1}];
|
|
* R.findLast(R.propEq('a', 1))(xs); //=> {a: 1, b: 1}
|
|
* R.findLast(R.propEq('a', 4))(xs); //=> undefined
|
|
*/
|
|
var findLast = _curry2(_dispatchable('findLast', _xfindLast, function findLast(fn, list) {
|
|
var idx = list.length - 1;
|
|
while (idx >= 0) {
|
|
if (fn(list[idx])) {
|
|
return list[idx];
|
|
}
|
|
idx -= 1;
|
|
}
|
|
}));
|
|
|
|
/**
|
|
* Returns the index of the last element of the list which matches the predicate, or
|
|
* `-1` if no element matches.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> Number
|
|
* @param {Function} fn The predicate function used to determine if the element is the
|
|
* desired one.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Number} The index of the element found, or `-1`.
|
|
* @example
|
|
*
|
|
* var xs = [{a: 1, b: 0}, {a:1, b: 1}];
|
|
* R.findLastIndex(R.propEq('a', 1))(xs); //=> 1
|
|
* R.findLastIndex(R.propEq('a', 4))(xs); //=> -1
|
|
*/
|
|
var findLastIndex = _curry2(_dispatchable('findLastIndex', _xfindLastIndex, function findLastIndex(fn, list) {
|
|
var idx = list.length - 1;
|
|
while (idx >= 0) {
|
|
if (fn(list[idx])) {
|
|
return idx;
|
|
}
|
|
idx -= 1;
|
|
}
|
|
return -1;
|
|
}));
|
|
|
|
/**
|
|
* Returns a new list by pulling every item out of it (and all its sub-arrays) and putting
|
|
* them in a new array, depth-first.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [b]
|
|
* @param {Array} list The array to consider.
|
|
* @return {Array} The flattened list.
|
|
* @example
|
|
*
|
|
* R.flatten([1, 2, [3, 4], 5, [6, [7, 8, [9, [10, 11], 12]]]]);
|
|
* //=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
|
*/
|
|
var flatten = _curry1(_makeFlat(true));
|
|
|
|
/**
|
|
* Iterate over an input `list`, calling a provided function `fn` for each element in the
|
|
* list.
|
|
*
|
|
* `fn` receives one argument: *(value)*.
|
|
*
|
|
* Note: `R.forEach` does not skip deleted or unassigned indices (sparse arrays), unlike
|
|
* the native `Array.prototype.forEach` method. For more details on this behavior, see:
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Description
|
|
*
|
|
* Also note that, unlike `Array.prototype.forEach`, Ramda's `forEach` returns the original
|
|
* array. In some libraries this function is named `each`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> *) -> [a] -> [a]
|
|
* @param {Function} fn The function to invoke. Receives one argument, `value`.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {Array} The original list.
|
|
* @example
|
|
*
|
|
* var printXPlusFive = function(x) { console.log(x + 5); };
|
|
* R.forEach(printXPlusFive, [1, 2, 3]); //=> [1, 2, 3]
|
|
* //-> 6
|
|
* //-> 7
|
|
* //-> 8
|
|
*/
|
|
var forEach = _curry2(function forEach(fn, list) {
|
|
return _hasMethod('forEach', list) ? list.forEach(fn) : _forEach(fn, list);
|
|
});
|
|
|
|
/**
|
|
* Returns a list of function names of object's own functions
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {*} -> [String]
|
|
* @param {Object} obj The objects with functions in it
|
|
* @return {Array} A list of the object's own properties that map to functions.
|
|
* @example
|
|
*
|
|
* R.functions(R); // returns list of ramda's own function names
|
|
*
|
|
* var F = function() { this.x = function(){}; this.y = 1; }
|
|
* F.prototype.z = function() {};
|
|
* F.prototype.a = 100;
|
|
* R.functions(new F()); //=> ["x"]
|
|
*/
|
|
var functions = _curry1(_functionsWith(keys));
|
|
|
|
/**
|
|
* Returns a list of function names of object's own and prototype functions
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {*} -> [String]
|
|
* @param {Object} obj The objects with functions in it
|
|
* @return {Array} A list of the object's own properties and prototype
|
|
* properties that map to functions.
|
|
* @example
|
|
*
|
|
* R.functionsIn(R); // returns list of ramda's own and prototype function names
|
|
*
|
|
* var F = function() { this.x = function(){}; this.y = 1; }
|
|
* F.prototype.z = function() {};
|
|
* F.prototype.a = 100;
|
|
* R.functionsIn(new F()); //=> ["x", "z"]
|
|
*/
|
|
var functionsIn = _curry1(_functionsWith(keysIn));
|
|
|
|
/**
|
|
* Splits a list into sub-lists stored in an object, based on the result of calling a String-returning function
|
|
* on each element, and grouping the results according to values returned.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> String) -> [a] -> {String: [a]}
|
|
* @param {Function} fn Function :: a -> String
|
|
* @param {Array} list The array to group
|
|
* @return {Object} An object with the output of `fn` for keys, mapped to arrays of elements
|
|
* that produced that key when passed to `fn`.
|
|
* @example
|
|
*
|
|
* var byGrade = R.groupBy(function(student) {
|
|
* var score = student.score;
|
|
* return score < 65 ? 'F' :
|
|
* score < 70 ? 'D' :
|
|
* score < 80 ? 'C' :
|
|
* score < 90 ? 'B' : 'A';
|
|
* });
|
|
* var students = [{name: 'Abby', score: 84},
|
|
* {name: 'Eddy', score: 58},
|
|
* // ...
|
|
* {name: 'Jack', score: 69}];
|
|
* byGrade(students);
|
|
* // {
|
|
* // 'A': [{name: 'Dianne', score: 99}],
|
|
* // 'B': [{name: 'Abby', score: 84}]
|
|
* // // ...,
|
|
* // 'F': [{name: 'Eddy', score: 58}]
|
|
* // }
|
|
*/
|
|
var groupBy = _curry2(_dispatchable('groupBy', _xgroupBy, function groupBy(fn, list) {
|
|
return _reduce(function (acc, elt) {
|
|
var key = fn(elt);
|
|
acc[key] = _append(elt, acc[key] || (acc[key] = []));
|
|
return acc;
|
|
}, {}, list);
|
|
}));
|
|
|
|
/**
|
|
* Returns the first element in a list.
|
|
* In some libraries this function is named `first`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> a
|
|
* @param {Array} list The array to consider.
|
|
* @return {*} The first element of the list, or `undefined` if the list is empty.
|
|
* @example
|
|
*
|
|
* R.head(['fi', 'fo', 'fum']); //=> 'fi'
|
|
*/
|
|
var head = nth(0);
|
|
|
|
/**
|
|
* Creates a function that will process either the `onTrue` or the `onFalse` function depending
|
|
* upon the result of the `condition` predicate.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig (*... -> Boolean) -> (*... -> *) -> (*... -> *) -> (*... -> *)
|
|
* @param {Function} condition A predicate function
|
|
* @param {Function} onTrue A function to invoke when the `condition` evaluates to a truthy value.
|
|
* @param {Function} onFalse A function to invoke when the `condition` evaluates to a falsy value.
|
|
* @return {Function} A new unary function that will process either the `onTrue` or the `onFalse`
|
|
* function depending upon the result of the `condition` predicate.
|
|
* @example
|
|
*
|
|
* // Flatten all arrays in the list but leave other values alone.
|
|
* var flattenArrays = R.map(R.ifElse(Array.isArray, R.flatten, R.identity));
|
|
*
|
|
* flattenArrays([[0], [[10], [8]], 1234, {}]); //=> [[0], [10, 8], 1234, {}]
|
|
* flattenArrays([[[10], 123], [8, [10]], "hello"]); //=> [[10, 123], [8, 10], "hello"]
|
|
*/
|
|
var ifElse = _curry3(function ifElse(condition, onTrue, onFalse) {
|
|
return curryN(Math.max(condition.length, onTrue.length, onFalse.length), function _ifElse() {
|
|
return condition.apply(this, arguments) ? onTrue.apply(this, arguments) : onFalse.apply(this, arguments);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Inserts the supplied element into the list, at index `index`. _Note
|
|
* that this is not destructive_: it returns a copy of the list with the changes.
|
|
* <small>No lists have been harmed in the application of this function.</small>
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> a -> [a] -> [a]
|
|
* @param {Number} index The position to insert the element
|
|
* @param {*} elt The element to insert into the Array
|
|
* @param {Array} list The list to insert into
|
|
* @return {Array} A new Array with `elt` inserted at `index`.
|
|
* @example
|
|
*
|
|
* R.insert(2, 'x', [1,2,3,4]); //=> [1,2,'x',3,4]
|
|
*/
|
|
var insert = _curry3(function insert(idx, elt, list) {
|
|
idx = idx < list.length && idx >= 0 ? idx : list.length;
|
|
return _concat(_append(elt, _slice(list, 0, idx)), _slice(list, idx));
|
|
});
|
|
|
|
/**
|
|
* Combines two lists into a set (i.e. no duplicates) composed of those
|
|
* elements common to both lists. Duplication is determined according
|
|
* to the value returned by applying the supplied predicate to two list
|
|
* elements.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig (a,a -> Boolean) -> [a] -> [a] -> [a]
|
|
* @param {Function} pred A predicate function that determines whether
|
|
* the two supplied elements are equal.
|
|
* @param {Array} list1 One list of items to compare
|
|
* @param {Array} list2 A second list of items to compare
|
|
* @see R.intersection
|
|
* @return {Array} A new list containing those elements common to both lists.
|
|
* @example
|
|
*
|
|
* var buffaloSpringfield = [
|
|
* {id: 824, name: 'Richie Furay'},
|
|
* {id: 956, name: 'Dewey Martin'},
|
|
* {id: 313, name: 'Bruce Palmer'},
|
|
* {id: 456, name: 'Stephen Stills'},
|
|
* {id: 177, name: 'Neil Young'}
|
|
* ];
|
|
* var csny = [
|
|
* {id: 204, name: 'David Crosby'},
|
|
* {id: 456, name: 'Stephen Stills'},
|
|
* {id: 539, name: 'Graham Nash'},
|
|
* {id: 177, name: 'Neil Young'}
|
|
* ];
|
|
*
|
|
* var sameId = function(o1, o2) {return o1.id === o2.id;};
|
|
*
|
|
* R.intersectionWith(sameId, buffaloSpringfield, csny);
|
|
* //=> [{id: 456, name: 'Stephen Stills'}, {id: 177, name: 'Neil Young'}]
|
|
*/
|
|
var intersectionWith = _curry3(function intersectionWith(pred, list1, list2) {
|
|
var results = [], idx = 0;
|
|
while (idx < list1.length) {
|
|
if (_containsWith(pred, list1[idx], list2)) {
|
|
results[results.length] = list1[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
return uniqWith(pred, results);
|
|
});
|
|
|
|
/**
|
|
* Creates a new list with the separator interposed between elements.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig a -> [a] -> [a]
|
|
* @param {*} separator The element to add to the list.
|
|
* @param {Array} list The list to be interposed.
|
|
* @return {Array} The new list.
|
|
* @example
|
|
*
|
|
* R.intersperse('n', ['ba', 'a', 'a']); //=> ['ba', 'n', 'a', 'n', 'a']
|
|
*/
|
|
var intersperse = _curry2(_checkForMethod('intersperse', function intersperse(separator, list) {
|
|
var out = [];
|
|
var idx = 0;
|
|
var length = list.length;
|
|
while (idx < length) {
|
|
if (idx === length - 1) {
|
|
out.push(list[idx]);
|
|
} else {
|
|
out.push(list[idx], separator);
|
|
}
|
|
idx += 1;
|
|
}
|
|
return out;
|
|
}));
|
|
|
|
/**
|
|
* Same as R.invertObj, however this accounts for objects
|
|
* with duplicate values by putting the values into an
|
|
* array.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {s: x} -> {x: [ s, ... ]}
|
|
* @param {Object} obj The object or array to invert
|
|
* @return {Object} out A new object with keys
|
|
* in an array.
|
|
* @example
|
|
*
|
|
* var raceResultsByFirstName = {
|
|
* first: 'alice',
|
|
* second: 'jake',
|
|
* third: 'alice',
|
|
* };
|
|
* R.invert(raceResultsByFirstName);
|
|
* //=> { 'alice': ['first', 'third'], 'jake':['second'] }
|
|
*/
|
|
var invert = _curry1(function invert(obj) {
|
|
var props = keys(obj);
|
|
var len = props.length;
|
|
var idx = 0;
|
|
var out = {};
|
|
while (idx < len) {
|
|
var key = props[idx];
|
|
var val = obj[key];
|
|
var list = _has(val, out) ? out[val] : out[val] = [];
|
|
list[list.length] = key;
|
|
idx += 1;
|
|
}
|
|
return out;
|
|
});
|
|
|
|
/**
|
|
* Returns a new object with the keys of the given object
|
|
* as values, and the values of the given object as keys.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {s: x} -> {x: s}
|
|
* @param {Object} obj The object or array to invert
|
|
* @return {Object} out A new object
|
|
* @example
|
|
*
|
|
* var raceResults = {
|
|
* first: 'alice',
|
|
* second: 'jake'
|
|
* };
|
|
* R.invertObj(raceResults);
|
|
* //=> { 'alice': 'first', 'jake':'second' }
|
|
*
|
|
* // Alternatively:
|
|
* var raceResults = ['alice', 'jake'];
|
|
* R.invertObj(raceResults);
|
|
* //=> { 'alice': '0', 'jake':'1' }
|
|
*/
|
|
var invertObj = _curry1(function invertObj(obj) {
|
|
var props = keys(obj);
|
|
var len = props.length;
|
|
var idx = 0;
|
|
var out = {};
|
|
while (idx < len) {
|
|
var key = props[idx];
|
|
out[obj[key]] = key;
|
|
idx += 1;
|
|
}
|
|
return out;
|
|
});
|
|
|
|
/**
|
|
* Turns a named method with a specified arity into a function
|
|
* that can be called directly supplied with arguments and a target object.
|
|
*
|
|
* The returned function is curried and accepts `arity + 1` parameters where
|
|
* the final parameter is the target object.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig Number -> String -> (a -> b -> ... -> n -> Object -> *)
|
|
* @param {Number} arity Number of arguments the returned function should take
|
|
* before the target object.
|
|
* @param {Function} method Name of the method to call.
|
|
* @return {Function} A new curried function.
|
|
* @example
|
|
*
|
|
* var sliceFrom = R.invoker(1, 'slice');
|
|
* sliceFrom(6, 'abcdefghijklm'); //=> 'ghijklm'
|
|
* var sliceFrom6 = R.invoker(2, 'slice')(6);
|
|
* sliceFrom6(8, 'abcdefghijklm'); //=> 'gh'
|
|
*/
|
|
var invoker = _curry2(function invoker(arity, method) {
|
|
return curryN(arity + 1, function () {
|
|
var target = arguments[arity];
|
|
return target[method].apply(target, _slice(arguments, 0, arity));
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Returns a string made by inserting the `separator` between each
|
|
* element and concatenating all the elements into a single string.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig String -> [a] -> String
|
|
* @param {Number|String} separator The string used to separate the elements.
|
|
* @param {Array} xs The elements to join into a string.
|
|
* @return {String} str The string made by concatenating `xs` with `separator`.
|
|
* @example
|
|
*
|
|
* var spacer = R.join(' ');
|
|
* spacer(['a', 2, 3.4]); //=> 'a 2 3.4'
|
|
* R.join('|', [1, 2, 3]); //=> '1|2|3'
|
|
*/
|
|
var join = invoker(1, 'join');
|
|
|
|
/**
|
|
* Returns the last element from a list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> a
|
|
* @param {Array} list The array to consider.
|
|
* @return {*} The last element of the list, or `undefined` if the list is empty.
|
|
* @example
|
|
*
|
|
* R.last(['fi', 'fo', 'fum']); //=> 'fum'
|
|
*/
|
|
var last = nth(-1);
|
|
|
|
/**
|
|
* Creates a lens that will focus on index `n` of the source array.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @see R.lens
|
|
* @sig Number -> (a -> b)
|
|
* @param {Number} n The index of the array that the returned lens will focus on.
|
|
* @return {Function} the returned function has `set` and `map` properties that are
|
|
* also curried functions.
|
|
* @example
|
|
*
|
|
* var headLens = R.lensIndex(0);
|
|
* headLens([10, 20, 30, 40]); //=> 10
|
|
* headLens.set('mu', [10, 20, 30, 40]); //=> ['mu', 20, 30, 40]
|
|
* headLens.map(function(x) { return x + 1; }, [10, 20, 30, 40]); //=> [11, 20, 30, 40]
|
|
*/
|
|
var lensIndex = _curry1(function lensIndex(n) {
|
|
return lens(nth(n), update(n));
|
|
});
|
|
|
|
/**
|
|
* Creates a lens that will focus on property `k` of the source object.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @see R.lens
|
|
* @sig String -> (a -> b)
|
|
* @param {String} k A string that represents a property to focus on.
|
|
* @return {Function} the returned function has `set` and `map` properties that are
|
|
* also curried functions.
|
|
* @example
|
|
*
|
|
* var phraseLens = R.lensProp('phrase');
|
|
* var obj1 = { phrase: 'Absolute filth . . . and I LOVED it!'};
|
|
* var obj2 = { phrase: "What's all this, then?"};
|
|
* phraseLens(obj1); // => 'Absolute filth . . . and I LOVED it!'
|
|
* phraseLens(obj2); // => "What's all this, then?"
|
|
* phraseLens.set('Ooh Betty', obj1); //=> { phrase: 'Ooh Betty'}
|
|
* phraseLens.map(R.toUpper, obj2); //=> { phrase: "WHAT'S ALL THIS, THEN?"}
|
|
*/
|
|
var lensProp = _curry1(function lensProp(k) {
|
|
return lens(prop(k), assoc(k));
|
|
});
|
|
|
|
/**
|
|
* Returns a new list, constructed by applying the supplied function to every element of the
|
|
* supplied list.
|
|
*
|
|
* Note: `R.map` does not skip deleted or unassigned indices (sparse arrays), unlike the
|
|
* native `Array.prototype.map` method. For more details on this behavior, see:
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#Description
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> b) -> [a] -> [b]
|
|
* @param {Function} fn The function to be called on every element of the input `list`.
|
|
* @param {Array} list The list to be iterated over.
|
|
* @return {Array} The new list.
|
|
* @example
|
|
*
|
|
* var double = function(x) {
|
|
* return x * 2;
|
|
* };
|
|
*
|
|
* R.map(double, [1, 2, 3]); //=> [2, 4, 6]
|
|
*/
|
|
var map = _curry2(_dispatchable('map', _xmap, _map));
|
|
|
|
/**
|
|
* Map, but for objects. Creates an object with the same keys as `obj` and values
|
|
* generated by running each property of `obj` through `fn`. `fn` is passed one argument:
|
|
* *(value)*.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig (v -> v) -> {k: v} -> {k: v}
|
|
* @param {Function} fn A function called for each property in `obj`. Its return value will
|
|
* become a new property on the return object.
|
|
* @param {Object} obj The object to iterate over.
|
|
* @return {Object} A new object with the same keys as `obj` and values that are the result
|
|
* of running each property through `fn`.
|
|
* @example
|
|
*
|
|
* var values = { x: 1, y: 2, z: 3 };
|
|
* var double = function(num) {
|
|
* return num * 2;
|
|
* };
|
|
*
|
|
* R.mapObj(double, values); //=> { x: 2, y: 4, z: 6 }
|
|
*/
|
|
var mapObj = _curry2(function mapObject(fn, obj) {
|
|
return _reduce(function (acc, key) {
|
|
acc[key] = fn(obj[key]);
|
|
return acc;
|
|
}, {}, keys(obj));
|
|
});
|
|
|
|
/**
|
|
* Like `mapObj`, but but passes additional arguments to the predicate function. The
|
|
* predicate function is passed three arguments: *(value, key, obj)*.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig (v, k, {k: v} -> v) -> {k: v} -> {k: v}
|
|
* @param {Function} fn A function called for each property in `obj`. Its return value will
|
|
* become a new property on the return object.
|
|
* @param {Object} obj The object to iterate over.
|
|
* @return {Object} A new object with the same keys as `obj` and values that are the result
|
|
* of running each property through `fn`.
|
|
* @example
|
|
*
|
|
* var values = { x: 1, y: 2, z: 3 };
|
|
* var prependKeyAndDouble = function(num, key, obj) {
|
|
* return key + (num * 2);
|
|
* };
|
|
*
|
|
* R.mapObjIndexed(prependKeyAndDouble, values); //=> { x: 'x2', y: 'y4', z: 'z6' }
|
|
*/
|
|
var mapObjIndexed = _curry2(function mapObjectIndexed(fn, obj) {
|
|
return _reduce(function (acc, key) {
|
|
acc[key] = fn(obj[key], key, obj);
|
|
return acc;
|
|
}, {}, keys(obj));
|
|
});
|
|
|
|
/**
|
|
* Tests a regular expression against a String
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig RegExp -> String -> [String] | null
|
|
* @param {RegExp} rx A regular expression.
|
|
* @param {String} str The string to match against
|
|
* @return {Array} The list of matches, or null if no matches found.
|
|
* @see R.invoker
|
|
* @example
|
|
*
|
|
* R.match(/([a-z]a)/g, 'bananas'); //=> ['ba', 'na', 'na']
|
|
*/
|
|
var match = invoker(1, 'match');
|
|
|
|
/**
|
|
* Determines the largest of a list of numbers (or elements that can be cast to numbers)
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig [Number] -> Number
|
|
* @see R.maxBy
|
|
* @param {Array} list A list of numbers
|
|
* @return {Number} The greatest number in the list.
|
|
* @example
|
|
*
|
|
* R.max([7, 3, 9, 2, 4, 9, 3]); //=> 9
|
|
*/
|
|
var max = _createMaxMin(_gt, -Infinity);
|
|
|
|
/**
|
|
* Create a new object with the own properties of `a`
|
|
* merged with the own properties of object `b`.
|
|
* This function will *not* mutate passed-in objects.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {k: v} -> {k: v} -> {k: v}
|
|
* @param {Object} a source object
|
|
* @param {Object} b object with higher precedence in output
|
|
* @return {Object} The destination object.
|
|
* @example
|
|
*
|
|
* R.merge({ 'name': 'fred', 'age': 10 }, { 'age': 40 });
|
|
* //=> { 'name': 'fred', 'age': 40 }
|
|
*
|
|
* var resetToDefault = R.merge(R.__, {x: 0});
|
|
* resetToDefault({x: 5, y: 2}); //=> {x: 0, y: 2}
|
|
*/
|
|
var merge = _curry2(function merge(a, b) {
|
|
return _extend(_extend({}, a), b);
|
|
});
|
|
|
|
/**
|
|
* Determines the smallest of a list of numbers (or elements that can be cast to numbers)
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig [Number] -> Number
|
|
* @param {Array} list A list of numbers
|
|
* @return {Number} The greatest number in the list.
|
|
* @see R.minBy
|
|
* @example
|
|
*
|
|
* R.min([7, 3, 9, 2, 4, 9, 3]); //=> 2
|
|
*/
|
|
var min = _createMaxMin(_lt, Infinity);
|
|
|
|
/**
|
|
* Returns `true` if no elements of the list match the predicate,
|
|
* `false` otherwise.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> Boolean
|
|
* @param {Function} fn The predicate function.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Boolean} `true` if the predicate is not satisfied by every element, `false` otherwise.
|
|
* @example
|
|
*
|
|
* R.none(R.isNaN, [1, 2, 3]); //=> true
|
|
* R.none(R.isNaN, [1, 2, 3, NaN]); //=> false
|
|
*/
|
|
var none = _curry2(_complement(_dispatchable('any', _xany, _any)));
|
|
|
|
/**
|
|
* A function that returns the first truthy of two arguments otherwise the
|
|
* last argument. Note that this is NOT short-circuited, meaning that if
|
|
* expressions are passed they are both evaluated.
|
|
*
|
|
* Dispatches to the `or` method of the first argument if applicable.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig * -> * -> *
|
|
* @param {*} a any value
|
|
* @param {*} b any other value
|
|
* @return {*} the first truthy argument, otherwise the last argument.
|
|
* @example
|
|
*
|
|
* R.or(false, true); //=> true
|
|
* R.or(0, []); //=> []
|
|
* R.or(null, ''); => ''
|
|
*/
|
|
var or = _curry2(function or(a, b) {
|
|
return _hasMethod('or', a) ? a.or(b) : a || b;
|
|
});
|
|
|
|
/**
|
|
* Takes a predicate and a list and returns the pair of lists of
|
|
* elements which do and do not satisfy the predicate, respectively.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> [[a],[a]]
|
|
* @param {Function} pred A predicate to determine which array the element belongs to.
|
|
* @param {Array} list The array to partition.
|
|
* @return {Array} A nested array, containing first an array of elements that satisfied the predicate,
|
|
* and second an array of elements that did not satisfy.
|
|
* @example
|
|
*
|
|
* R.partition(R.contains('s'), ['sss', 'ttt', 'foo', 'bars']);
|
|
* //=> [ [ 'sss', 'bars' ], [ 'ttt', 'foo' ] ]
|
|
*/
|
|
var partition = _curry2(function partition(pred, list) {
|
|
return _reduce(function (acc, elt) {
|
|
var xs = acc[pred(elt) ? 0 : 1];
|
|
xs[xs.length] = elt;
|
|
return acc;
|
|
}, [
|
|
[],
|
|
[]
|
|
], list);
|
|
});
|
|
|
|
/**
|
|
* Determines whether a nested path on an object has a specific value,
|
|
* in `R.equals` terms. Most likely used to filter a list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig [String] -> * -> {String: *} -> Boolean
|
|
* @param {Array} path The path of the nested property to use
|
|
* @param {*} val The value to compare the nested property with
|
|
* @param {Object} obj The object to check the nested property in
|
|
* @return {Boolean} `true` if the value equals the nested object property,
|
|
* `false` otherwise.
|
|
* @example
|
|
*
|
|
* var user1 = { address: { zipCode: 90210 } };
|
|
* var user2 = { address: { zipCode: 55555 } };
|
|
* var user3 = { name: 'Bob' };
|
|
* var users = [ user1, user2, user3 ];
|
|
* var isFamous = R.pathEq(['address', 'zipCode'], 90210);
|
|
* R.filter(isFamous, users); //=> [ user1 ]
|
|
*/
|
|
var pathEq = _curry3(function pathEq(path, val, obj) {
|
|
return equals(_path(path, obj), val);
|
|
});
|
|
|
|
/**
|
|
* Creates a new function that runs each of the functions supplied as parameters in turn,
|
|
* passing the return value of each function invocation to the next function invocation,
|
|
* beginning with whatever arguments were passed to the initial invocation.
|
|
*
|
|
* `pipe` is the mirror version of `compose`. `pipe` is left-associative, which means that
|
|
* each of the functions provided is executed in order from left to right.
|
|
*
|
|
* In some libraries this function is named `sequence`.
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig ((a... -> b), (b -> c), ..., (x -> y), (y -> z)) -> (a... -> z)
|
|
* @param {...Function} functions A variable number of functions.
|
|
* @return {Function} A new function which represents the result of calling each of the
|
|
* input `functions`, passing the result of each function call to the next, from
|
|
* left to right.
|
|
* @example
|
|
*
|
|
* var triple = function(x) { return x * 3; };
|
|
* var double = function(x) { return x * 2; };
|
|
* var square = function(x) { return x * x; };
|
|
* var squareThenDoubleThenTriple = R.pipe(square, double, triple);
|
|
*
|
|
* //≅ triple(double(square(5)))
|
|
* squareThenDoubleThenTriple(5); //=> 150
|
|
*/
|
|
var pipe = function pipe() {
|
|
return compose.apply(this, reverse(arguments));
|
|
};
|
|
|
|
/**
|
|
* Creates a new lens that allows getting and setting values of nested properties, by
|
|
* following each given lens in succession.
|
|
*
|
|
* `pipeL` is the mirror version of `composeL`. `pipeL` is left-associative, which means that
|
|
* each of the functions provided is executed in order from left to right.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @see R.lens
|
|
* @sig ((a -> b), (b -> c), ..., (x -> y), (y -> z)) -> (a -> z)
|
|
* @param {...Function} lenses A variable number of lenses.
|
|
* @return {Function} A new lens which represents the result of calling each of the
|
|
* input `lenses`, passing the result of each getter/setter as the source
|
|
* to the next, from right to left.
|
|
* @example
|
|
*
|
|
* var headLens = R.lensIndex(0);
|
|
* var secondLens = R.lensIndex(1);
|
|
* var xLens = R.lensProp('x');
|
|
* var headThenXThenSecondLens = R.pipeL(headLens, xLens, secondLens);
|
|
*
|
|
* var source = [{x: [0, 1], y: [2, 3]}, {x: [4, 5], y: [6, 7]}];
|
|
* headThenXThenSecondLens(source); //=> 1
|
|
* headThenXThenSecondLens.set(123, source); //=> [{x: [0, 123], y: [2, 3]}, {x: [4, 5], y: [6, 7]}]
|
|
*/
|
|
var pipeL = compose(apply(composeL), unapply(reverse));
|
|
|
|
/**
|
|
* Creates a new function that runs each of the functions supplied as parameters in turn,
|
|
* passing to the next function invocation either the value returned by the previous
|
|
* function or the resolved value if the returned value is a promise. In other words,
|
|
* if some of the functions in the sequence return promises, `pipeP` pipes the values
|
|
* asynchronously. If none of the functions return promises, the behavior is the same as
|
|
* that of `pipe`.
|
|
*
|
|
* `pipeP` is the mirror version of `composeP`. `pipeP` is left-associative, which means that
|
|
* each of the functions provided is executed in order from left to right.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig ((a... -> b), (b -> c), ..., (x -> y), (y -> z)) -> (a... -> z)
|
|
* @param {...Function} functions A variable number of functions.
|
|
* @return {Function} A new function which represents the result of calling each of the
|
|
* input `functions`, passing either the returned result or the asynchronously
|
|
* resolved value) of each function call to the next, from left to right.
|
|
* @example
|
|
*
|
|
* var Q = require('q');
|
|
* var triple = function(x) { return x * 3; };
|
|
* var double = function(x) { return x * 2; };
|
|
* var squareAsync = function(x) { return Q.when(x * x); };
|
|
* var squareAsyncThenDoubleThenTriple = R.pipeP(squareAsync, double, triple);
|
|
*
|
|
* //≅ squareAsync(5).then(function(x) { return triple(double(x)) };
|
|
* squareAsyncThenDoubleThenTriple(5)
|
|
* .then(function(result) {
|
|
* // result is 150
|
|
* });
|
|
*/
|
|
var pipeP = function pipeP() {
|
|
return composeP.apply(this, reverse(arguments));
|
|
};
|
|
|
|
/**
|
|
* Determines whether the given property of an object has a specific value,
|
|
* in `R.equals` terms. Most likely used to filter a list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig k -> v -> {k: v} -> Boolean
|
|
* @param {Number|String} name The property name (or index) to use.
|
|
* @param {*} val The value to compare the property with.
|
|
* @return {Boolean} `true` if the properties are equal, `false` otherwise.
|
|
* @example
|
|
*
|
|
* var abby = {name: 'Abby', age: 7, hair: 'blond'};
|
|
* var fred = {name: 'Fred', age: 12, hair: 'brown'};
|
|
* var rusty = {name: 'Rusty', age: 10, hair: 'brown'};
|
|
* var alois = {name: 'Alois', age: 15, disposition: 'surly'};
|
|
* var kids = [abby, fred, rusty, alois];
|
|
* var hasBrownHair = R.propEq('hair', 'brown');
|
|
* R.filter(hasBrownHair, kids); //=> [fred, rusty]
|
|
*/
|
|
var propEq = _curry3(function propEq(name, val, obj) {
|
|
return equals(obj[name], val);
|
|
});
|
|
|
|
/**
|
|
* Returns a single item by iterating through the list, successively calling the iterator
|
|
* function and passing it an accumulator value and the current value from the array, and
|
|
* then passing the result to the next call.
|
|
*
|
|
* The iterator function receives two values: *(acc, value)*. It may use `R.reduced` to
|
|
* shortcut the iteration.
|
|
*
|
|
* Note: `R.reduce` does not skip deleted or unassigned indices (sparse arrays), unlike
|
|
* the native `Array.prototype.reduce` method. For more details on this behavior, see:
|
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Description
|
|
* @see R.reduced
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a,b -> a) -> a -> [b] -> a
|
|
* @param {Function} fn The iterator function. Receives two values, the accumulator and the
|
|
* current element from the array.
|
|
* @param {*} acc The accumulator value.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {*} The final, accumulated value.
|
|
* @example
|
|
*
|
|
* var numbers = [1, 2, 3];
|
|
* var add = function(a, b) {
|
|
* return a + b;
|
|
* };
|
|
*
|
|
* R.reduce(add, 10, numbers); //=> 16
|
|
*/
|
|
var reduce = _curry3(_reduce);
|
|
|
|
/**
|
|
* Similar to `filter`, except that it keeps only values for which the given predicate
|
|
* function returns falsy. The predicate function is passed one argument: *(value)*.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> [a]
|
|
* @param {Function} fn The function called per iteration.
|
|
* @param {Array} list The collection to iterate over.
|
|
* @return {Array} The new filtered array.
|
|
* @example
|
|
*
|
|
* var isOdd = function(n) {
|
|
* return n % 2 === 1;
|
|
* };
|
|
* R.reject(isOdd, [1, 2, 3, 4]); //=> [2, 4]
|
|
*/
|
|
var reject = _curry2(function reject(fn, list) {
|
|
return filter(_complement(fn), list);
|
|
});
|
|
|
|
/**
|
|
* Returns a fixed list of size `n` containing a specified identical value.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig a -> n -> [a]
|
|
* @param {*} value The value to repeat.
|
|
* @param {Number} n The desired size of the output list.
|
|
* @return {Array} A new array containing `n` `value`s.
|
|
* @example
|
|
*
|
|
* R.repeat('hi', 5); //=> ['hi', 'hi', 'hi', 'hi', 'hi']
|
|
*
|
|
* var obj = {};
|
|
* var repeatedObjs = R.repeat(obj, 5); //=> [{}, {}, {}, {}, {}]
|
|
* repeatedObjs[0] === repeatedObjs[1]; //=> true
|
|
*/
|
|
var repeat = _curry2(function repeat(value, n) {
|
|
return times(always(value), n);
|
|
});
|
|
|
|
/**
|
|
* Returns a list containing the elements of `xs` from `fromIndex` (inclusive)
|
|
* to `toIndex` (exclusive).
|
|
*
|
|
* Dispatches to its third argument's `slice` method if present. As a
|
|
* result, one may replace `[a]` with `String` in the type signature.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> Number -> [a] -> [a]
|
|
* @param {Number} fromIndex The start index (inclusive).
|
|
* @param {Number} toIndex The end index (exclusive).
|
|
* @param {Array} xs The list to take elements from.
|
|
* @return {Array} The slice of `xs` from `fromIndex` to `toIndex`.
|
|
* @example
|
|
*
|
|
* R.slice(1, 3, ['a', 'b', 'c', 'd']); //=> ['b', 'c']
|
|
* R.slice(1, Infinity, ['a', 'b', 'c', 'd']); //=> ['b', 'c', 'd']
|
|
* R.slice(0, -1, ['a', 'b', 'c', 'd']); //=> ['a', 'b', 'c']
|
|
* R.slice(-3, -1, ['a', 'b', 'c', 'd']); //=> ['b', 'c']
|
|
* R.slice(0, 3, 'ramda'); //=> 'ram'
|
|
*/
|
|
var slice = _curry3(_checkForMethod('slice', function slice(fromIndex, toIndex, xs) {
|
|
return Array.prototype.slice.call(xs, fromIndex, toIndex);
|
|
}));
|
|
|
|
/**
|
|
* Splits a string into an array of strings based on the given
|
|
* separator.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig String -> String -> [String]
|
|
* @param {String} sep The separator string.
|
|
* @param {String} str The string to separate into an array.
|
|
* @return {Array} The array of strings from `str` separated by `str`.
|
|
* @example
|
|
*
|
|
* var pathComponents = R.split('/');
|
|
* R.tail(pathComponents('/usr/local/bin/node')); //=> ['usr', 'local', 'bin', 'node']
|
|
*
|
|
* R.split('.', 'a.b.c.xyz.d'); //=> ['a', 'b', 'c', 'xyz', 'd']
|
|
*/
|
|
var split = invoker(1, 'split');
|
|
|
|
/**
|
|
* Returns a string containing the characters of `str` from `fromIndex`
|
|
* (inclusive) to `toIndex` (exclusive).
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig Number -> Number -> String -> String
|
|
* @param {Number} fromIndex The start index (inclusive).
|
|
* @param {Number} toIndex The end index (exclusive).
|
|
* @param {String} str The string to slice.
|
|
* @return {String}
|
|
* @see R.slice
|
|
* @deprecated since v0.15.0
|
|
* @example
|
|
*
|
|
* R.substring(2, 5, 'abcdefghijklm'); //=> 'cde'
|
|
*/
|
|
var substring = slice;
|
|
|
|
/**
|
|
* Returns a string containing the characters of `str` from `fromIndex`
|
|
* (inclusive) to the end of `str`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig Number -> String -> String
|
|
* @param {Number} fromIndex
|
|
* @param {String} str
|
|
* @return {String}
|
|
* @deprecated since v0.15.0
|
|
* @example
|
|
*
|
|
* R.substringFrom(3, 'Ramda'); //=> 'da'
|
|
* R.substringFrom(-2, 'Ramda'); //=> 'da'
|
|
*/
|
|
var substringFrom = substring(__, Infinity);
|
|
|
|
/**
|
|
* Returns a string containing the first `toIndex` characters of `str`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig Number -> String -> String
|
|
* @param {Number} toIndex
|
|
* @param {String} str
|
|
* @return {String}
|
|
* @deprecated since v0.15.0
|
|
* @example
|
|
*
|
|
* R.substringTo(3, 'Ramda'); //=> 'Ram'
|
|
* R.substringTo(-2, 'Ramda'); //=> 'Ram'
|
|
*/
|
|
var substringTo = substring(0);
|
|
|
|
/**
|
|
* Adds together all the elements of a list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig [Number] -> Number
|
|
* @param {Array} list An array of numbers
|
|
* @return {Number} The sum of all the numbers in the list.
|
|
* @see R.reduce
|
|
* @example
|
|
*
|
|
* R.sum([2,4,6,8,100,1]); //=> 121
|
|
*/
|
|
var sum = reduce(_add, 0);
|
|
|
|
/**
|
|
* Returns all but the first element of a list. If the list provided has the `tail` method,
|
|
* it will instead return `list.tail()`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [a]
|
|
* @param {Array} list The array to consider.
|
|
* @return {Array} A new array containing all but the first element of the input list, or an
|
|
* empty list if the input list is empty.
|
|
* @example
|
|
*
|
|
* R.tail(['fi', 'fo', 'fum']); //=> ['fo', 'fum']
|
|
*/
|
|
var tail = _checkForMethod('tail', function (list) {
|
|
return _slice(list, 1);
|
|
});
|
|
|
|
/**
|
|
* Returns a new list containing the first `n` elements of the given list.
|
|
* If `n > list.length`, returns a list of `list.length` elements.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* Dispatches to its second argument's `slice` method if present. As a
|
|
* result, one may replace `[a]` with `String` in the type signature.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> [a] -> [a]
|
|
* @param {Number} n The number of elements to return.
|
|
* @param {Array} xs The collection to consider.
|
|
* @return {Array}
|
|
* @example
|
|
*
|
|
* R.take(1, ['foo', 'bar', 'baz']); //=> ['foo']
|
|
* R.take(2, ['foo', 'bar', 'baz']); //=> ['foo', 'bar']
|
|
* R.take(3, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz']
|
|
* R.take(4, ['foo', 'bar', 'baz']); //=> ['foo', 'bar', 'baz']
|
|
* R.take(3, 'ramda'); //=> 'ram'
|
|
*
|
|
* var personnel = [
|
|
* 'Dave Brubeck',
|
|
* 'Paul Desmond',
|
|
* 'Eugene Wright',
|
|
* 'Joe Morello',
|
|
* 'Gerry Mulligan',
|
|
* 'Bob Bates',
|
|
* 'Joe Dodge',
|
|
* 'Ron Crotty'
|
|
* ];
|
|
*
|
|
* takeFive(personnel);
|
|
* //=> ['Dave Brubeck', 'Paul Desmond', 'Eugene Wright', 'Joe Morello', 'Gerry Mulligan']
|
|
*/
|
|
var take = _curry2(_dispatchable('take', _xtake, function take(n, xs) {
|
|
return slice(0, n < 0 ? Infinity : n, xs);
|
|
}));
|
|
|
|
/**
|
|
* Returns a new list containing the first `n` elements of a given list, passing each value
|
|
* to the supplied predicate function, and terminating when the predicate function returns
|
|
* `false`. Excludes the element that caused the predicate function to fail. The predicate
|
|
* function is passed one argument: *(value)*.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> Boolean) -> [a] -> [a]
|
|
* @param {Function} fn The function called per iteration.
|
|
* @param {Array} list The collection to iterate over.
|
|
* @return {Array} A new array.
|
|
* @example
|
|
*
|
|
* var isNotFour = function(x) {
|
|
* return !(x === 4);
|
|
* };
|
|
*
|
|
* R.takeWhile(isNotFour, [1, 2, 3, 4]); //=> [1, 2, 3]
|
|
*/
|
|
var takeWhile = _curry2(_dispatchable('takeWhile', _xtakeWhile, function takeWhile(fn, list) {
|
|
var idx = 0, len = list.length;
|
|
while (idx < len && fn(list[idx])) {
|
|
idx += 1;
|
|
}
|
|
return _slice(list, 0, idx);
|
|
}));
|
|
|
|
/**
|
|
* The lower case version of a string.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig String -> String
|
|
* @param {String} str The string to lower case.
|
|
* @return {String} The lower case version of `str`.
|
|
* @example
|
|
*
|
|
* R.toLower('XYZ'); //=> 'xyz'
|
|
*/
|
|
var toLower = invoker(0, 'toLowerCase');
|
|
|
|
/**
|
|
* The upper case version of a string.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig String -> String
|
|
* @param {String} str The string to upper case.
|
|
* @return {String} The upper case version of `str`.
|
|
* @example
|
|
*
|
|
* R.toUpper('abc'); //=> 'ABC'
|
|
*/
|
|
var toUpper = invoker(0, 'toUpperCase');
|
|
|
|
/**
|
|
* Initializes a transducer using supplied iterator function. Returns a single item by
|
|
* iterating through the list, successively calling the transformed iterator function and
|
|
* passing it an accumulator value and the current value from the array, and then passing
|
|
* the result to the next call.
|
|
*
|
|
* The iterator function receives two values: *(acc, value)*. It will be wrapped as a
|
|
* transformer to initialize the transducer. A transformer can be passed directly in place
|
|
* of an iterator function. In both cases, iteration may be stopped early with the
|
|
* `R.reduced` function.
|
|
*
|
|
* A transducer is a function that accepts a transformer and returns a transformer and can
|
|
* be composed directly.
|
|
*
|
|
* A transformer is an an object that provides a 2-arity reducing iterator function, step,
|
|
* 0-arity initial value function, init, and 1-arity result extraction function, result.
|
|
* The step function is used as the iterator function in reduce. The result function is used
|
|
* to convert the final accumulator into the return type and in most cases is R.identity.
|
|
* The init function can be used to provide an initial accumulator, but is ignored by transduce.
|
|
*
|
|
* The iteration is performed with R.reduce after initializing the transducer.
|
|
* @see R.reduce
|
|
* @see R.reduced
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (c -> c) -> (a,b -> a) -> a -> [b] -> a
|
|
* @param {Function} xf The transducer function. Receives a transformer and returns a transformer.
|
|
* @param {Function} fn The iterator function. Receives two values, the accumulator and the
|
|
* current element from the array. Wrapped as transformer, if necessary, and used to
|
|
* initialize the transducer
|
|
* @param {*} acc The initial accumulator value.
|
|
* @param {Array} list The list to iterate over.
|
|
* @see R.into
|
|
* @return {*} The final, accumulated value.
|
|
* @example
|
|
*
|
|
* var numbers = [1, 2, 3, 4];
|
|
* var transducer = R.compose(R.map(R.add(1)), R.take(2));
|
|
*
|
|
* R.transduce(transducer, R.flip(R.append), [], numbers); //=> [2, 3]
|
|
*/
|
|
var transduce = curryN(4, function (xf, fn, acc, list) {
|
|
return _reduce(xf(typeof fn === 'function' ? _xwrap(fn) : fn), acc, list);
|
|
});
|
|
|
|
/**
|
|
* Returns a function of arity `n` from a (manually) curried function.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig Number -> (a -> b) -> (a -> c)
|
|
* @param {Number} length The arity for the returned function.
|
|
* @param {Function} fn The function to uncurry.
|
|
* @return {Function} A new function.
|
|
* @see R.curry
|
|
* @example
|
|
*
|
|
* var addFour = function(a) {
|
|
* return function(b) {
|
|
* return function(c) {
|
|
* return function(d) {
|
|
* return a + b + c + d;
|
|
* };
|
|
* };
|
|
* };
|
|
* };
|
|
*
|
|
* var uncurriedAddFour = R.uncurryN(4, addFour);
|
|
* curriedAddFour(1, 2, 3, 4); //=> 10
|
|
*/
|
|
var uncurryN = _curry2(function uncurryN(depth, fn) {
|
|
return curryN(depth, function () {
|
|
var currentDepth = 1;
|
|
var value = fn;
|
|
var idx = 0;
|
|
var endIdx;
|
|
while (currentDepth <= depth && typeof value === 'function') {
|
|
endIdx = currentDepth === depth ? arguments.length : idx + value.length;
|
|
value = value.apply(this, _slice(arguments, idx, endIdx));
|
|
currentDepth += 1;
|
|
idx = endIdx;
|
|
}
|
|
return value;
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Combines two lists into a set (i.e. no duplicates) composed of the elements of each list. Duplication is
|
|
* determined according to the value returned by applying the supplied predicate to two list elements.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig (a,a -> Boolean) -> [a] -> [a] -> [a]
|
|
* @param {Function} pred A predicate used to test whether two items are equal.
|
|
* @param {Array} list1 The first list.
|
|
* @param {Array} list2 The second list.
|
|
* @return {Array} The first and second lists concatenated, with
|
|
* duplicates removed.
|
|
* @see R.union
|
|
* @example
|
|
*
|
|
* function cmp(x, y) { return x.a === y.a; }
|
|
* var l1 = [{a: 1}, {a: 2}];
|
|
* var l2 = [{a: 1}, {a: 4}];
|
|
* R.unionWith(cmp, l1, l2); //=> [{a: 1}, {a: 2}, {a: 4}]
|
|
*/
|
|
var unionWith = _curry3(function unionWith(pred, list1, list2) {
|
|
return uniqWith(pred, _concat(list1, list2));
|
|
});
|
|
|
|
/**
|
|
* Returns a new list containing only one copy of each element in the original list.
|
|
* `R.equals` is used to determine equality.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [a]
|
|
* @param {Array} list The array to consider.
|
|
* @return {Array} The list of unique items.
|
|
* @example
|
|
*
|
|
* R.uniq([1, 1, 2, 1]); //=> [1, 2]
|
|
* R.uniq([1, '1']); //=> [1, '1']
|
|
* R.uniq([[42], [42]]); //=> [[42]]
|
|
*/
|
|
var uniq = uniqWith(equals);
|
|
|
|
/**
|
|
* Returns a new list by pulling every item at the first level of nesting out, and putting
|
|
* them in a new array.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [b]
|
|
* @param {Array} list The array to consider.
|
|
* @return {Array} The flattened list.
|
|
* @example
|
|
*
|
|
* R.unnest([1, [2], [[3]]]); //=> [1, 2, [3]]
|
|
* R.unnest([[1, 2], [3, 4], [5, 6]]); //=> [1, 2, 3, 4, 5, 6]
|
|
*/
|
|
var unnest = _curry1(_makeFlat(false));
|
|
|
|
/**
|
|
* Takes a spec object and a test object; returns true if the test satisfies
|
|
* the spec, false otherwise. An object satisfies the spec if, for each of the
|
|
* spec's own properties, accessing that property of the object gives the same
|
|
* value (in `R.equals` terms) as accessing that property of the spec.
|
|
*
|
|
* `whereEq` is a specialization of [`where`](#where).
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig {String: *} -> {String: *} -> Boolean
|
|
* @param {Object} spec
|
|
* @param {Object} testObj
|
|
* @return {Boolean}
|
|
* @see R.where
|
|
* @example
|
|
*
|
|
* // pred :: Object -> Boolean
|
|
* var pred = R.whereEq({a: 1, b: 2});
|
|
*
|
|
* pred({a: 1}); //=> false
|
|
* pred({a: 1, b: 2}); //=> true
|
|
* pred({a: 1, b: 2, c: 3}); //=> true
|
|
* pred({a: 1, b: 1}); //=> false
|
|
*/
|
|
var whereEq = _curry2(function whereEq(spec, testObj) {
|
|
return where(mapObj(equals, spec), testObj);
|
|
});
|
|
|
|
/**
|
|
* Wrap a function inside another to allow you to make adjustments to the parameters, or do
|
|
* other processing either before the internal function is called or with its results.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (a... -> b) -> ((a... -> b) -> a... -> c) -> (a... -> c)
|
|
* @param {Function} fn The function to wrap.
|
|
* @param {Function} wrapper The wrapper function.
|
|
* @return {Function} The wrapped function.
|
|
* @example
|
|
*
|
|
* var greet = function(name) {return 'Hello ' + name;};
|
|
*
|
|
* var shoutedGreet = R.wrap(greet, function(gr, name) {
|
|
* return gr(name).toUpperCase();
|
|
* });
|
|
* shoutedGreet("Kathy"); //=> "HELLO KATHY"
|
|
*
|
|
* var shortenedGreet = R.wrap(greet, function(gr, name) {
|
|
* return gr(name.substring(0, 3));
|
|
* });
|
|
* shortenedGreet("Robert"); //=> "Hello Rob"
|
|
*/
|
|
var wrap = _curry2(function wrap(fn, wrapper) {
|
|
return curryN(fn.length, function () {
|
|
return wrapper.apply(this, _concat([fn], arguments));
|
|
});
|
|
});
|
|
|
|
var _chain = _curry2(function _chain(f, list) {
|
|
return unnest(map(f, list));
|
|
});
|
|
|
|
var _flatCat = function () {
|
|
var preservingReduced = function (xf) {
|
|
return {
|
|
'@@transducer/init': _xfBase.init,
|
|
'@@transducer/result': function (result) {
|
|
return xf['@@transducer/result'](result);
|
|
},
|
|
'@@transducer/step': function (result, input) {
|
|
var ret = xf['@@transducer/step'](result, input);
|
|
return ret['@@transducer/reduced'] ? _forceReduced(ret) : ret;
|
|
}
|
|
};
|
|
};
|
|
return function _xcat(xf) {
|
|
var rxf = preservingReduced(xf);
|
|
return {
|
|
'@@transducer/init': _xfBase.init,
|
|
'@@transducer/result': function (result) {
|
|
return rxf['@@transducer/result'](result);
|
|
},
|
|
'@@transducer/step': function (result, input) {
|
|
return !isArrayLike(input) ? _reduce(rxf, result, [input]) : _reduce(rxf, result, input);
|
|
}
|
|
};
|
|
};
|
|
}();
|
|
|
|
var _indexOf = function _indexOf(list, item, from) {
|
|
var idx = 0, len = list.length;
|
|
if (typeof from === 'number') {
|
|
idx = from < 0 ? Math.max(0, len + from) : from;
|
|
}
|
|
while (idx < len) {
|
|
if (equals(list[idx], item)) {
|
|
return idx;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
var _lastIndexOf = function _lastIndexOf(list, item, from) {
|
|
var idx;
|
|
if (typeof from === 'number') {
|
|
idx = from < 0 ? list.length + from : Math.min(list.length - 1, from);
|
|
} else {
|
|
idx = list.length - 1;
|
|
}
|
|
while (idx >= 0) {
|
|
if (equals(list[idx], item)) {
|
|
return idx;
|
|
}
|
|
idx -= 1;
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
var _pluck = function _pluck(p, list) {
|
|
return map(prop(p), list);
|
|
};
|
|
|
|
/**
|
|
* Create a predicate wrapper which will call a pick function (all/any) for each predicate
|
|
*
|
|
* @private
|
|
* @see R.all
|
|
* @see R.any
|
|
*/
|
|
// Call function immediately if given arguments
|
|
// Return a function which will call the predicates with the provided arguments
|
|
var _predicateWrap = function _predicateWrap(predPicker) {
|
|
return function (preds) {
|
|
var predIterator = function () {
|
|
var args = arguments;
|
|
return predPicker(function (predicate) {
|
|
return predicate.apply(null, args);
|
|
}, preds);
|
|
};
|
|
return arguments.length > 1 ? // Call function immediately if given arguments
|
|
predIterator.apply(null, _slice(arguments, 1)) : // Return a function which will call the predicates with the provided arguments
|
|
arity(max(_pluck('length', preds)), predIterator);
|
|
};
|
|
};
|
|
|
|
var _stepCat = function () {
|
|
var _stepCatArray = {
|
|
'@@transducer/init': Array,
|
|
'@@transducer/step': function (xs, x) {
|
|
return _concat(xs, [x]);
|
|
},
|
|
'@@transducer/result': _identity
|
|
};
|
|
var _stepCatString = {
|
|
'@@transducer/init': String,
|
|
'@@transducer/step': _add,
|
|
'@@transducer/result': _identity
|
|
};
|
|
var _stepCatObject = {
|
|
'@@transducer/init': Object,
|
|
'@@transducer/step': function (result, input) {
|
|
return merge(result, isArrayLike(input) ? _createMapEntry(input[0], input[1]) : input);
|
|
},
|
|
'@@transducer/result': _identity
|
|
};
|
|
return function _stepCat(obj) {
|
|
if (_isTransformer(obj)) {
|
|
return obj;
|
|
}
|
|
if (isArrayLike(obj)) {
|
|
return _stepCatArray;
|
|
}
|
|
if (typeof obj === 'string') {
|
|
return _stepCatString;
|
|
}
|
|
if (typeof obj === 'object') {
|
|
return _stepCatObject;
|
|
}
|
|
throw new Error('Cannot create transformer for ' + obj);
|
|
};
|
|
}();
|
|
|
|
// Function, RegExp, user-defined types
|
|
var _toString = function _toString(x, seen) {
|
|
var recur = function recur(y) {
|
|
var xs = seen.concat([x]);
|
|
return _indexOf(xs, y) >= 0 ? '<Circular>' : _toString(y, xs);
|
|
};
|
|
switch (Object.prototype.toString.call(x)) {
|
|
case '[object Arguments]':
|
|
return '(function() { return arguments; }(' + _map(recur, x).join(', ') + '))';
|
|
case '[object Array]':
|
|
return '[' + _map(recur, x).join(', ') + ']';
|
|
case '[object Boolean]':
|
|
return typeof x === 'object' ? 'new Boolean(' + recur(x.valueOf()) + ')' : x.toString();
|
|
case '[object Date]':
|
|
return 'new Date(' + _quote(_toISOString(x)) + ')';
|
|
case '[object Null]':
|
|
return 'null';
|
|
case '[object Number]':
|
|
return typeof x === 'object' ? 'new Number(' + recur(x.valueOf()) + ')' : 1 / x === -Infinity ? '-0' : x.toString(10);
|
|
case '[object String]':
|
|
return typeof x === 'object' ? 'new String(' + recur(x.valueOf()) + ')' : _quote(x);
|
|
case '[object Undefined]':
|
|
return 'undefined';
|
|
default:
|
|
return typeof x.constructor === 'function' && x.constructor.name !== 'Object' && typeof x.toString === 'function' && x.toString() !== '[object Object]' ? x.toString() : // Function, RegExp, user-defined types
|
|
'{' + _map(function (k) {
|
|
return _quote(k) + ': ' + recur(x[k]);
|
|
}, keys(x).sort()).join(', ') + '}';
|
|
}
|
|
};
|
|
|
|
var _xchain = _curry2(function _xchain(f, xf) {
|
|
return map(f, _flatCat(xf));
|
|
});
|
|
|
|
/**
|
|
* Creates a new list iteration function from an existing one by adding two new parameters
|
|
* to its callback function: the current index, and the entire list.
|
|
*
|
|
* This would turn, for instance, Ramda's simple `map` function into one that more closely
|
|
* resembles `Array.prototype.map`. Note that this will only work for functions in which
|
|
* the iteration callback function is the first parameter, and where the list is the last
|
|
* parameter. (This latter might be unimportant if the list parameter is not used.)
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @category List
|
|
* @sig ((a ... -> b) ... -> [a] -> *) -> (a ..., Int, [a] -> b) ... -> [a] -> *)
|
|
* @param {Function} fn A list iteration function that does not pass index/list to its callback
|
|
* @return An altered list iteration function thats passes index/list to its callback
|
|
* @example
|
|
*
|
|
* var mapIndexed = R.addIndex(R.map);
|
|
* mapIndexed(function(val, idx) {return idx + '-' + val;}, ['f', 'o', 'o', 'b', 'a', 'r']);
|
|
* //=> ['0-f', '1-o', '2-o', '3-b', '4-a', '5-r']
|
|
*/
|
|
var addIndex = _curry1(function (fn) {
|
|
return curryN(fn.length, function () {
|
|
var idx = 0;
|
|
var origFn = arguments[0];
|
|
var list = arguments[arguments.length - 1];
|
|
var indexedFn = function () {
|
|
var result = origFn.apply(this, _concat(arguments, [
|
|
idx,
|
|
list
|
|
]));
|
|
idx += 1;
|
|
return result;
|
|
};
|
|
return fn.apply(this, _prepend(indexedFn, _slice(arguments, 1)));
|
|
});
|
|
});
|
|
|
|
/**
|
|
* ap applies a list of functions to a list of values.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig [f] -> [a] -> [f a]
|
|
* @param {Array} fns An array of functions
|
|
* @param {Array} vs An array of values
|
|
* @return {Array} An array of results of applying each of `fns` to all of `vs` in turn.
|
|
* @example
|
|
*
|
|
* R.ap([R.multiply(2), R.add(3)], [1,2,3]); //=> [2, 4, 6, 4, 5, 6]
|
|
*/
|
|
var ap = _curry2(function ap(fns, vs) {
|
|
return _hasMethod('ap', fns) ? fns.ap(vs) : _reduce(function (acc, fn) {
|
|
return _concat(acc, map(fn, vs));
|
|
}, [], fns);
|
|
});
|
|
|
|
/**
|
|
* `chain` maps a function over a list and concatenates the results.
|
|
* This implementation is compatible with the
|
|
* Fantasy-land Chain spec, and will work with types that implement that spec.
|
|
* `chain` is also known as `flatMap` in some libraries
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a -> [b]) -> [a] -> [b]
|
|
* @param {Function} fn
|
|
* @param {Array} list
|
|
* @return {Array}
|
|
* @example
|
|
*
|
|
* var duplicate = function(n) {
|
|
* return [n, n];
|
|
* };
|
|
* R.chain(duplicate, [1, 2, 3]); //=> [1, 1, 2, 2, 3, 3]
|
|
*/
|
|
var chain = _curry2(_dispatchable('chain', _xchain, _chain));
|
|
|
|
/**
|
|
* Turns a list of Functors into a Functor of a list, applying
|
|
* a mapping function to the elements of the list along the way.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @see R.commute
|
|
* @sig Functor f => (f a -> f b) -> (x -> f x) -> [f a] -> f [b]
|
|
* @param {Function} fn The transformation function
|
|
* @param {Function} of A function that returns the data type to return
|
|
* @param {Array} list An array of functors of the same type
|
|
* @return {*}
|
|
* @example
|
|
*
|
|
* R.commuteMap(R.map(R.add(10)), R.of, [[1], [2, 3]]); //=> [[11, 12], [11, 13]]
|
|
* R.commuteMap(R.map(R.add(10)), R.of, [[1, 2], [3]]); //=> [[11, 13], [12, 13]]
|
|
* R.commuteMap(R.map(R.add(10)), R.of, [[1], [2], [3]]); //=> [[11, 12, 13]]
|
|
* R.commuteMap(R.map(R.add(10)), Maybe.of, [Just(1), Just(2), Just(3)]); //=> Just([11, 12, 13])
|
|
* R.commuteMap(R.map(R.add(10)), Maybe.of, [Just(1), Just(2), Nothing()]); //=> Nothing()
|
|
*/
|
|
var commuteMap = _curry3(function commuteMap(fn, of, list) {
|
|
function consF(acc, ftor) {
|
|
return ap(map(append, fn(ftor)), acc);
|
|
}
|
|
return _reduce(consF, of([]), list);
|
|
});
|
|
|
|
/**
|
|
* Returns a curried equivalent of the provided function. The curried
|
|
* function has two unusual capabilities. First, its arguments needn't
|
|
* be provided one at a time. If `f` is a ternary function and `g` is
|
|
* `R.curry(f)`, the following are equivalent:
|
|
*
|
|
* - `g(1)(2)(3)`
|
|
* - `g(1)(2, 3)`
|
|
* - `g(1, 2)(3)`
|
|
* - `g(1, 2, 3)`
|
|
*
|
|
* Secondly, the special placeholder value `R.__` may be used to specify
|
|
* "gaps", allowing partial application of any combination of arguments,
|
|
* regardless of their positions. If `g` is as above and `_` is `R.__`,
|
|
* the following are equivalent:
|
|
*
|
|
* - `g(1, 2, 3)`
|
|
* - `g(_, 2, 3)(1)`
|
|
* - `g(_, _, 3)(1)(2)`
|
|
* - `g(_, _, 3)(1, 2)`
|
|
* - `g(_, 2)(1)(3)`
|
|
* - `g(_, 2)(1, 3)`
|
|
* - `g(_, 2)(_, 3)(1)`
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (* -> a) -> (* -> a)
|
|
* @param {Function} fn The function to curry.
|
|
* @return {Function} A new, curried function.
|
|
* @see R.curryN
|
|
* @example
|
|
*
|
|
* var addFourNumbers = function(a, b, c, d) {
|
|
* return a + b + c + d;
|
|
* };
|
|
*
|
|
* var curriedAddFourNumbers = R.curry(addFourNumbers);
|
|
* var f = curriedAddFourNumbers(1, 2);
|
|
* var g = f(3);
|
|
* g(4); //=> 10
|
|
*/
|
|
var curry = _curry1(function curry(fn) {
|
|
return curryN(fn.length, fn);
|
|
});
|
|
|
|
/**
|
|
* Returns a list containing all but the first `n` elements of the given `list`.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* Dispatches to its second argument's `slice` method if present. As a
|
|
* result, one may replace `[a]` with `String` in the type signature.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig Number -> [a] -> [a]
|
|
* @param {Number} n The number of elements of `xs` to skip.
|
|
* @param {Array} xs The collection to consider.
|
|
* @return {Array}
|
|
* @example
|
|
*
|
|
* R.drop(1, ['foo', 'bar', 'baz']); //=> ['bar', 'baz']
|
|
* R.drop(2, ['foo', 'bar', 'baz']); //=> ['baz']
|
|
* R.drop(3, ['foo', 'bar', 'baz']); //=> []
|
|
* R.drop(4, ['foo', 'bar', 'baz']); //=> []
|
|
* R.drop(3, 'ramda'); //=> 'da'
|
|
*/
|
|
var drop = _curry2(_dispatchable('drop', _xdrop, function drop(n, xs) {
|
|
return slice(Math.max(0, n), Infinity, xs);
|
|
}));
|
|
|
|
/**
|
|
* Returns a new list without any consecutively repeating elements. Equality is
|
|
* determined by applying the supplied predicate two consecutive elements.
|
|
* The first element in a series of equal element is the one being preserved.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig (a, a -> Boolean) -> [a] -> [a]
|
|
* @param {Function} pred A predicate used to test whether two items are equal.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Array} `list` without repeating elements.
|
|
* @example
|
|
*
|
|
* function lengthEq(x, y) { return Math.abs(x) === Math.abs(y); };
|
|
* var l = [1, -1, 1, 3, 4, -4, -4, -5, 5, 3, 3];
|
|
* R.dropRepeatsWith(lengthEq, l); //=> [1, 3, 4, -5, 3]
|
|
*/
|
|
var dropRepeatsWith = _curry2(_dispatchable('dropRepeatsWith', _xdropRepeatsWith, function dropRepeatsWith(pred, list) {
|
|
var result = [];
|
|
var idx = 1;
|
|
var len = list.length;
|
|
if (len !== 0) {
|
|
result[0] = list[0];
|
|
while (idx < len) {
|
|
if (!pred(last(result), list[idx])) {
|
|
result[result.length] = list[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
}
|
|
return result;
|
|
}));
|
|
|
|
/**
|
|
* Performs a deep test on whether two items are equal.
|
|
* Equality implies the two items are semmatically equivalent.
|
|
* Cyclic structures are handled as expected
|
|
* @see R.equals
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig a -> b -> Boolean
|
|
* @param {*} a
|
|
* @param {*} b
|
|
* @return {Boolean}
|
|
* @deprecated since v0.15.0
|
|
* @example
|
|
*
|
|
* var o = {};
|
|
* R.eqDeep(o, o); //=> true
|
|
* R.eqDeep(o, {}); //=> true
|
|
* R.eqDeep(1, 1); //=> true
|
|
* R.eqDeep(1, '1'); //=> false
|
|
*
|
|
* var a = {}; a.v = a;
|
|
* var b = {}; b.v = b;
|
|
* R.eqDeep(a, b); //=> true
|
|
*/
|
|
var eqDeep = equals;
|
|
|
|
/**
|
|
* Reports whether two objects have the same value, in `R.equals` terms,
|
|
* for the specified property. Useful as a curried predicate.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig k -> {k: v} -> {k: v} -> Boolean
|
|
* @param {String} prop The name of the property to compare
|
|
* @param {Object} obj1
|
|
* @param {Object} obj2
|
|
* @return {Boolean}
|
|
*
|
|
* @example
|
|
*
|
|
* var o1 = { a: 1, b: 2, c: 3, d: 4 };
|
|
* var o2 = { a: 10, b: 20, c: 3, d: 40 };
|
|
* R.eqProps('a', o1, o2); //=> false
|
|
* R.eqProps('c', o1, o2); //=> true
|
|
*/
|
|
var eqProps = _curry3(function eqProps(prop, obj1, obj2) {
|
|
return equals(obj1[prop], obj2[prop]);
|
|
});
|
|
|
|
/**
|
|
* Returns a new function much like the supplied one, except that the first two arguments'
|
|
* order is reversed.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (a -> b -> c -> ... -> z) -> (b -> a -> c -> ... -> z)
|
|
* @param {Function} fn The function to invoke with its first two parameters reversed.
|
|
* @return {*} The result of invoking `fn` with its first two parameters' order reversed.
|
|
* @example
|
|
*
|
|
* var mergeThree = function(a, b, c) {
|
|
* return ([]).concat(a, b, c);
|
|
* };
|
|
*
|
|
* mergeThree(1, 2, 3); //=> [1, 2, 3]
|
|
*
|
|
* R.flip(mergeThree)(1, 2, 3); //=> [2, 1, 3]
|
|
*/
|
|
var flip = _curry1(function flip(fn) {
|
|
return curry(function (a, b) {
|
|
var args = _slice(arguments);
|
|
args[0] = b;
|
|
args[1] = a;
|
|
return fn.apply(this, args);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Returns the position of the first occurrence of an item in an array,
|
|
* or -1 if the item is not included in the array. `R.equals` is used to
|
|
* determine equality.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig a -> [a] -> Number
|
|
* @param {*} target The item to find.
|
|
* @param {Array} xs The array to search in.
|
|
* @return {Number} the index of the target, or -1 if the target is not found.
|
|
*
|
|
* @example
|
|
*
|
|
* R.indexOf(3, [1,2,3,4]); //=> 2
|
|
* R.indexOf(10, [1,2,3,4]); //=> -1
|
|
*/
|
|
var indexOf = _curry2(function indexOf(target, xs) {
|
|
return _hasMethod('indexOf', xs) ? xs.indexOf(target) : _indexOf(xs, target);
|
|
});
|
|
|
|
/**
|
|
* Returns all but the last element of a list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [a]
|
|
* @param {Array} list The array to consider.
|
|
* @return {Array} A new array containing all but the last element of the input list, or an
|
|
* empty list if the input list is empty.
|
|
* @example
|
|
*
|
|
* R.init(['fi', 'fo', 'fum']); //=> ['fi', 'fo']
|
|
*/
|
|
var init = slice(0, -1);
|
|
|
|
/**
|
|
* Transforms the items of the list with the transducer and appends the transformed items to
|
|
* the accumulator using an appropriate iterator function based on the accumulator type.
|
|
*
|
|
* The accumulator can be an array, string, object or a transformer. Iterated items will
|
|
* be appended to arrays and concatenated to strings. Objects will be merged directly or 2-item
|
|
* arrays will be merged as key, value pairs.
|
|
*
|
|
* The accumulator can also be a transformer object that provides a 2-arity reducing iterator
|
|
* function, step, 0-arity initial value function, init, and 1-arity result extraction function
|
|
* result. The step function is used as the iterator function in reduce. The result function is
|
|
* used to convert the final accumulator into the return type and in most cases is R.identity.
|
|
* The init function is used to provide the initial accumulator.
|
|
*
|
|
* The iteration is performed with R.reduce after initializing the transducer.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig a -> (b -> b) -> [c] -> a
|
|
* @param {*} acc The initial accumulator value.
|
|
* @param {Function} xf The transducer function. Receives a transformer and returns a transformer.
|
|
* @param {Array} list The list to iterate over.
|
|
* @return {*} The final, accumulated value.
|
|
* @example
|
|
*
|
|
* var numbers = [1, 2, 3, 4];
|
|
* var transducer = R.compose(R.map(R.add(1)), R.take(2));
|
|
*
|
|
* R.into([], transducer, numbers); //=> [2, 3]
|
|
*
|
|
* var intoArray = R.into([]);
|
|
* intoArray(transducer, numbers); //=> [2, 3]
|
|
*/
|
|
var into = _curry3(function into(acc, xf, list) {
|
|
return _isTransformer(acc) ? _reduce(xf(acc), acc['@@transducer/init'](), list) : _reduce(xf(_stepCat(acc)), acc, list);
|
|
});
|
|
|
|
/**
|
|
* Returns the result of applying `obj[methodName]` to `args`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig String -> [*] -> Object -> *
|
|
* @param {String} methodName
|
|
* @param {Array} args
|
|
* @param {Object} obj
|
|
* @return {*}
|
|
* @deprecated since v0.15.0
|
|
* @example
|
|
*
|
|
* // toBinary :: Number -> String
|
|
* var toBinary = R.invoke('toString', [2])
|
|
*
|
|
* toBinary(42); //=> '101010'
|
|
* toBinary(63); //=> '111111'
|
|
*/
|
|
var invoke = curry(function invoke(methodName, args, obj) {
|
|
return obj[methodName].apply(obj, args);
|
|
});
|
|
|
|
/**
|
|
* Returns `true` if all elements are unique, in `R.equals` terms,
|
|
* otherwise `false`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> Boolean
|
|
* @param {Array} list The array to consider.
|
|
* @return {Boolean} `true` if all elements are unique, else `false`.
|
|
* @example
|
|
*
|
|
* R.isSet(['1', 1]); //=> true
|
|
* R.isSet([1, 1]); //=> false
|
|
* R.isSet([[42], [42]]); //=> false
|
|
*/
|
|
var isSet = _curry1(function isSet(list) {
|
|
var len = list.length;
|
|
var idx = 0;
|
|
while (idx < len) {
|
|
if (_indexOf(list, list[idx], idx + 1) >= 0) {
|
|
return false;
|
|
}
|
|
idx += 1;
|
|
}
|
|
return true;
|
|
});
|
|
|
|
/**
|
|
* Returns the position of the last occurrence of an item in
|
|
* an array, or -1 if the item is not included in the array.
|
|
* `R.equals` is used to determine equality.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig a -> [a] -> Number
|
|
* @param {*} target The item to find.
|
|
* @param {Array} xs The array to search in.
|
|
* @return {Number} the index of the target, or -1 if the target is not found.
|
|
*
|
|
* @example
|
|
*
|
|
* R.lastIndexOf(3, [-1,3,3,0,1,2,3,4]); //=> 6
|
|
* R.lastIndexOf(10, [1,2,3,4]); //=> -1
|
|
*/
|
|
var lastIndexOf = _curry2(function lastIndexOf(target, xs) {
|
|
return _hasMethod('lastIndexOf', xs) ? xs.lastIndexOf(target) : _lastIndexOf(xs, target);
|
|
});
|
|
|
|
/**
|
|
* "lifts" a function to be the specified arity, so that it may "map over" that many
|
|
* lists (or other Functors).
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @see R.lift
|
|
* @category Function
|
|
* @sig Number -> (*... -> *) -> ([*]... -> [*])
|
|
* @param {Function} fn The function to lift into higher context
|
|
* @return {Function} The function `fn` applicable to mappable objects.
|
|
* @example
|
|
*
|
|
* var madd3 = R.liftN(3, R.curryN(3, function() {
|
|
* return R.reduce(R.add, 0, arguments);
|
|
* }));
|
|
* madd3([1,2,3], [1,2,3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7]
|
|
*/
|
|
var liftN = _curry2(function liftN(arity, fn) {
|
|
var lifted = curryN(arity, fn);
|
|
return curryN(arity, function () {
|
|
return _reduce(ap, map(lifted, arguments[0]), _slice(arguments, 1));
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Returns the mean of the given list of numbers.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig [Number] -> Number
|
|
* @param {Array} list
|
|
* @return {Number}
|
|
* @example
|
|
*
|
|
* R.mean([2, 7, 9]); //=> 6
|
|
* R.mean([]); //=> NaN
|
|
*/
|
|
var mean = _curry1(function mean(list) {
|
|
return sum(list) / list.length;
|
|
});
|
|
|
|
/**
|
|
* Returns the median of the given list of numbers.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig [Number] -> Number
|
|
* @param {Array} list
|
|
* @return {Number}
|
|
* @example
|
|
*
|
|
* R.median([2, 9, 7]); //=> 7
|
|
* R.median([7, 2, 10, 9]); //=> 8
|
|
* R.median([]); //=> NaN
|
|
*/
|
|
var median = _curry1(function median(list) {
|
|
var len = list.length;
|
|
if (len === 0) {
|
|
return NaN;
|
|
}
|
|
var width = 2 - len % 2;
|
|
var idx = (len - width) / 2;
|
|
return mean(_slice(list).sort(function (a, b) {
|
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
}).slice(idx, idx + width));
|
|
});
|
|
|
|
/**
|
|
* Merges a list of objects together into one object.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [{k: v}] -> {k: v}
|
|
* @param {Array} list An array of objects
|
|
* @return {Object} A merged object.
|
|
* @see R.reduce
|
|
* @example
|
|
*
|
|
* R.mergeAll([{foo:1},{bar:2},{baz:3}]); //=> {foo:1,bar:2,baz:3}
|
|
* R.mergeAll([{foo:1},{foo:2},{bar:2}]); //=> {foo:2,bar:2}
|
|
*/
|
|
var mergeAll = _curry1(function mergeAll(list) {
|
|
return reduce(merge, {}, list);
|
|
});
|
|
|
|
/**
|
|
* Returns a partial copy of an object omitting the keys specified.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @sig [String] -> {String: *} -> {String: *}
|
|
* @param {Array} names an array of String property names to omit from the new object
|
|
* @param {Object} obj The object to copy from
|
|
* @return {Object} A new object with properties from `names` not on it.
|
|
* @example
|
|
*
|
|
* R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}
|
|
*/
|
|
var omit = _curry2(function omit(names, obj) {
|
|
var result = {};
|
|
for (var prop in obj) {
|
|
if (_indexOf(names, prop) < 0) {
|
|
result[prop] = obj[prop];
|
|
}
|
|
}
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Accepts as its arguments a function and any number of values and returns a function that,
|
|
* when invoked, calls the original function with all of the values prepended to the
|
|
* original function's arguments list. In some libraries this function is named `applyLeft`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (a -> b -> ... -> i -> j -> ... -> m -> n) -> a -> b-> ... -> i -> (j -> ... -> m -> n)
|
|
* @param {Function} fn The function to invoke.
|
|
* @param {...*} [args] Arguments to prepend to `fn` when the returned function is invoked.
|
|
* @return {Function} A new function wrapping `fn`. When invoked, it will call `fn`
|
|
* with `args` prepended to `fn`'s arguments list.
|
|
* @example
|
|
*
|
|
* var multiply = function(a, b) { return a * b; };
|
|
* var double = R.partial(multiply, 2);
|
|
* double(2); //=> 4
|
|
*
|
|
* var greet = function(salutation, title, firstName, lastName) {
|
|
* return salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!';
|
|
* };
|
|
* var sayHello = R.partial(greet, 'Hello');
|
|
* var sayHelloToMs = R.partial(sayHello, 'Ms.');
|
|
* sayHelloToMs('Jane', 'Jones'); //=> 'Hello, Ms. Jane Jones!'
|
|
*/
|
|
var partial = curry(_createPartialApplicator(_concat));
|
|
|
|
/**
|
|
* Accepts as its arguments a function and any number of values and returns a function that,
|
|
* when invoked, calls the original function with all of the values appended to the original
|
|
* function's arguments list.
|
|
*
|
|
* Note that `partialRight` is the opposite of `partial`: `partialRight` fills `fn`'s arguments
|
|
* from the right to the left. In some libraries this function is named `applyRight`.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (a -> b-> ... -> i -> j -> ... -> m -> n) -> j -> ... -> m -> n -> (a -> b-> ... -> i)
|
|
* @param {Function} fn The function to invoke.
|
|
* @param {...*} [args] Arguments to append to `fn` when the returned function is invoked.
|
|
* @return {Function} A new function wrapping `fn`. When invoked, it will call `fn` with
|
|
* `args` appended to `fn`'s arguments list.
|
|
* @example
|
|
*
|
|
* var greet = function(salutation, title, firstName, lastName) {
|
|
* return salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!';
|
|
* };
|
|
* var greetMsJaneJones = R.partialRight(greet, 'Ms.', 'Jane', 'Jones');
|
|
*
|
|
* greetMsJaneJones('Hello'); //=> 'Hello, Ms. Jane Jones!'
|
|
*/
|
|
var partialRight = curry(_createPartialApplicator(flip(_concat)));
|
|
|
|
/**
|
|
* Returns a new list by plucking the same named property off all objects in the list supplied.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig k -> [{k: v}] -> [v]
|
|
* @param {Number|String} key The key name to pluck off of each object.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Array} The list of values for the given key.
|
|
* @example
|
|
*
|
|
* R.pluck('a')([{a: 1}, {a: 2}]); //=> [1, 2]
|
|
* R.pluck(0)([[1, 2], [3, 4]]); //=> [1, 3]
|
|
*/
|
|
var pluck = _curry2(_pluck);
|
|
|
|
/**
|
|
* Multiplies together all the elements of a list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Math
|
|
* @sig [Number] -> Number
|
|
* @param {Array} list An array of numbers
|
|
* @return {Number} The product of all the numbers in the list.
|
|
* @see R.reduce
|
|
* @example
|
|
*
|
|
* R.product([2,4,6,8,100,1]); //=> 38400
|
|
*/
|
|
var product = reduce(_multiply, 1);
|
|
|
|
/**
|
|
* Returns the string representation of the given value. `eval`'ing the output
|
|
* should result in a value equivalent to the input value. Many of the built-in
|
|
* `toString` methods do not satisfy this requirement.
|
|
*
|
|
* If the given value is an `[object Object]` with a `toString` method other
|
|
* than `Object.prototype.toString`, this method is invoked with no arguments
|
|
* to produce the return value. This means user-defined constructor functions
|
|
* can provide a suitable `toString` method. For example:
|
|
*
|
|
* function Point(x, y) {
|
|
* this.x = x;
|
|
* this.y = y;
|
|
* }
|
|
*
|
|
* Point.prototype.toString = function() {
|
|
* return 'new Point(' + this.x + ', ' + this.y + ')';
|
|
* };
|
|
*
|
|
* R.toString(new Point(1, 2)); //=> 'new Point(1, 2)'
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category String
|
|
* @sig * -> String
|
|
* @param {*} val
|
|
* @return {String}
|
|
* @example
|
|
*
|
|
* R.toString(42); //=> '42'
|
|
* R.toString('abc'); //=> '"abc"'
|
|
* R.toString([1, 2, 3]); //=> '[1, 2, 3]'
|
|
* R.toString({foo: 1, bar: 2, baz: 3}); //=> '{"bar": 2, "baz": 3, "foo": 1}'
|
|
* R.toString(new Date('2001-02-03T04:05:06Z')); //=> 'new Date("2001-02-03T04:05:06.000Z")'
|
|
*/
|
|
var toString = _curry1(function toString(val) {
|
|
return _toString(val, []);
|
|
});
|
|
|
|
/**
|
|
* Combines two lists into a set (i.e. no duplicates) composed of the
|
|
* elements of each list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig [a] -> [a] -> [a]
|
|
* @param {Array} as The first list.
|
|
* @param {Array} bs The second list.
|
|
* @return {Array} The first and second lists concatenated, with
|
|
* duplicates removed.
|
|
* @example
|
|
*
|
|
* R.union([1, 2, 3], [2, 3, 4]); //=> [1, 2, 3, 4]
|
|
*/
|
|
var union = _curry2(compose(uniq, _concat));
|
|
|
|
/**
|
|
* Accepts a function `fn` and any number of transformer functions and returns a new
|
|
* function. When the new function is invoked, it calls the function `fn` with parameters
|
|
* consisting of the result of calling each supplied handler on successive arguments to the
|
|
* new function.
|
|
*
|
|
* If more arguments are passed to the returned function than transformer functions, those
|
|
* arguments are passed directly to `fn` as additional parameters. If you expect additional
|
|
* arguments that don't need to be transformed, although you can ignore them, it's best to
|
|
* pass an identity function so that the new function reports the correct arity.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (x1 -> x2 -> ... -> z) -> ((a -> x1), (b -> x2), ...) -> (a -> b -> ... -> z)
|
|
* @param {Function} fn The function to wrap.
|
|
* @param {...Function} transformers A variable number of transformer functions
|
|
* @return {Function} The wrapped function.
|
|
* @example
|
|
*
|
|
* // Example 1:
|
|
*
|
|
* // Number -> [Person] -> [Person]
|
|
* var byAge = R.useWith(R.filter, R.propEq('age'), R.identity);
|
|
*
|
|
* var kids = [
|
|
* {name: 'Abbie', age: 6},
|
|
* {name: 'Brian', age: 5},
|
|
* {name: 'Chris', age: 6},
|
|
* {name: 'David', age: 4},
|
|
* {name: 'Ellie', age: 5}
|
|
* ];
|
|
*
|
|
* byAge(5, kids); //=> [{name: 'Brian', age: 5}, {name: 'Ellie', age: 5}]
|
|
*
|
|
* // Example 2:
|
|
*
|
|
* var double = function(y) { return y * 2; };
|
|
* var square = function(x) { return x * x; };
|
|
* var add = function(a, b) { return a + b; };
|
|
* // Adds any number of arguments together
|
|
* var addAll = function() {
|
|
* return R.reduce(add, 0, arguments);
|
|
* };
|
|
*
|
|
* // Basic example
|
|
* var addDoubleAndSquare = R.useWith(addAll, double, square);
|
|
*
|
|
* //≅ addAll(double(10), square(5));
|
|
* addDoubleAndSquare(10, 5); //=> 45
|
|
*
|
|
* // Example of passing more arguments than transformers
|
|
* //≅ addAll(double(10), square(5), 100);
|
|
* addDoubleAndSquare(10, 5, 100); //=> 145
|
|
*
|
|
* // If there are extra _expected_ arguments that don't need to be transformed, although
|
|
* // you can ignore them, it might be best to pass in the identity function so that the new
|
|
* // function correctly reports arity.
|
|
* var addDoubleAndSquareWithExtraParams = R.useWith(addAll, double, square, R.identity);
|
|
* // addDoubleAndSquareWithExtraParams.length //=> 3
|
|
* //≅ addAll(double(10), square(5), R.identity(100));
|
|
* addDoubleAndSquare(10, 5, 100); //=> 145
|
|
*/
|
|
/*, transformers */
|
|
var useWith = curry(function useWith(fn) {
|
|
var transformers = _slice(arguments, 1);
|
|
var tlen = transformers.length;
|
|
return curry(arity(tlen, function () {
|
|
var args = [], idx = 0;
|
|
while (idx < tlen) {
|
|
args[idx] = transformers[idx](arguments[idx]);
|
|
idx += 1;
|
|
}
|
|
return fn.apply(this, args.concat(_slice(arguments, tlen)));
|
|
}));
|
|
});
|
|
|
|
var _contains = function _contains(a, list) {
|
|
return _indexOf(list, a) >= 0;
|
|
};
|
|
|
|
/**
|
|
* Given a list of predicates, returns a new predicate that will be true exactly when all of them are.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig [(*... -> Boolean)] -> (*... -> Boolean)
|
|
* @param {Array} list An array of predicate functions
|
|
* @param {*} optional Any arguments to pass into the predicates
|
|
* @return {Function} a function that applies its arguments to each of
|
|
* the predicates, returning `true` if all are satisfied.
|
|
* @example
|
|
*
|
|
* var gt10 = function(x) { return x > 10; };
|
|
* var even = function(x) { return x % 2 === 0};
|
|
* var f = R.allPass([gt10, even]);
|
|
* f(11); //=> false
|
|
* f(12); //=> true
|
|
*/
|
|
var allPass = curry(_predicateWrap(_all));
|
|
|
|
/**
|
|
* Given a list of predicates returns a new predicate that will be true exactly when any one of them is.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Logic
|
|
* @sig [(*... -> Boolean)] -> (*... -> Boolean)
|
|
* @param {Array} list An array of predicate functions
|
|
* @param {*} optional Any arguments to pass into the predicates
|
|
* @return {Function} A function that applies its arguments to each of the predicates, returning
|
|
* `true` if all are satisfied.
|
|
* @example
|
|
*
|
|
* var gt10 = function(x) { return x > 10; };
|
|
* var even = function(x) { return x % 2 === 0};
|
|
* var f = R.anyPass([gt10, even]);
|
|
* f(11); //=> true
|
|
* f(8); //=> true
|
|
* f(9); //=> false
|
|
*/
|
|
var anyPass = curry(_predicateWrap(_any));
|
|
|
|
/**
|
|
* Returns the result of calling its first argument with the remaining
|
|
* arguments. This is occasionally useful as a converging function for
|
|
* `R.converge`: the left branch can produce a function while the right
|
|
* branch produces a value to be passed to that function as an argument.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (*... -> a),*... -> a
|
|
* @param {Function} fn The function to apply to the remaining arguments.
|
|
* @param {...*} args Any number of positional arguments.
|
|
* @return {*}
|
|
* @example
|
|
*
|
|
* var indentN = R.pipe(R.times(R.always(' ')),
|
|
* R.join(''),
|
|
* R.replace(/^(?!$)/gm));
|
|
*
|
|
* var format = R.converge(R.call,
|
|
* R.pipe(R.prop('indent'), indentN),
|
|
* R.prop('value'));
|
|
*
|
|
* format({indent: 2, value: 'foo\nbar\nbaz\n'}); //=> ' foo\n bar\n baz\n'
|
|
*/
|
|
var call = curry(function call(fn) {
|
|
return fn.apply(this, _slice(arguments, 1));
|
|
});
|
|
|
|
/**
|
|
* Turns a list of Functors into a Functor of a list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @see R.commuteMap
|
|
* @sig Functor f => (x -> f x) -> [f a] -> f [a]
|
|
* @param {Function} of A function that returns the data type to return
|
|
* @param {Array} list An array of functors of the same type
|
|
* @return {*}
|
|
* @example
|
|
*
|
|
* R.commute(R.of, [[1], [2, 3]]); //=> [[1, 2], [1, 3]]
|
|
* R.commute(R.of, [[1, 2], [3]]); //=> [[1, 3], [2, 3]]
|
|
* R.commute(R.of, [[1], [2], [3]]); //=> [[1, 2, 3]]
|
|
* R.commute(Maybe.of, [Just(1), Just(2), Just(3)]); //=> Just([1, 2, 3])
|
|
* R.commute(Maybe.of, [Just(1), Just(2), Nothing()]); //=> Nothing()
|
|
*/
|
|
var commute = commuteMap(map(identity));
|
|
|
|
/**
|
|
* Wraps a constructor function inside a curried function that can be called with the same
|
|
* arguments and returns the same type. The arity of the function returned is specified
|
|
* to allow using variadic constructor functions.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig Number -> (* -> {*}) -> (* -> {*})
|
|
* @param {Number} n The arity of the constructor function.
|
|
* @param {Function} Fn The constructor function to wrap.
|
|
* @return {Function} A wrapped, curried constructor function.
|
|
* @example
|
|
*
|
|
* // Variadic constructor function
|
|
* var Widget = function() {
|
|
* this.children = Array.prototype.slice.call(arguments);
|
|
* // ...
|
|
* };
|
|
* Widget.prototype = {
|
|
* // ...
|
|
* };
|
|
* var allConfigs = [
|
|
* // ...
|
|
* ];
|
|
* R.map(R.constructN(1, Widget), allConfigs); // a list of Widgets
|
|
*/
|
|
var constructN = _curry2(function constructN(n, Fn) {
|
|
if (n > 10) {
|
|
throw new Error('Constructor with greater than ten arguments');
|
|
}
|
|
if (n === 0) {
|
|
return function () {
|
|
return new Fn();
|
|
};
|
|
}
|
|
return curry(nAry(n, function ($0, $1, $2, $3, $4, $5, $6, $7, $8, $9) {
|
|
switch (arguments.length) {
|
|
case 1:
|
|
return new Fn($0);
|
|
case 2:
|
|
return new Fn($0, $1);
|
|
case 3:
|
|
return new Fn($0, $1, $2);
|
|
case 4:
|
|
return new Fn($0, $1, $2, $3);
|
|
case 5:
|
|
return new Fn($0, $1, $2, $3, $4);
|
|
case 6:
|
|
return new Fn($0, $1, $2, $3, $4, $5);
|
|
case 7:
|
|
return new Fn($0, $1, $2, $3, $4, $5, $6);
|
|
case 8:
|
|
return new Fn($0, $1, $2, $3, $4, $5, $6, $7);
|
|
case 9:
|
|
return new Fn($0, $1, $2, $3, $4, $5, $6, $7, $8);
|
|
case 10:
|
|
return new Fn($0, $1, $2, $3, $4, $5, $6, $7, $8, $9);
|
|
}
|
|
}));
|
|
});
|
|
|
|
/**
|
|
* Returns `true` if the specified value is equal, in `R.equals` terms,
|
|
* to at least one element of the given list; `false` otherwise.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig a -> [a] -> Boolean
|
|
* @param {Object} a The item to compare against.
|
|
* @param {Array} list The array to consider.
|
|
* @return {Boolean} `true` if the item is in the list, `false` otherwise.
|
|
*
|
|
* @example
|
|
*
|
|
* R.contains(3, [1, 2, 3]); //=> true
|
|
* R.contains(4, [1, 2, 3]); //=> false
|
|
* R.contains([42], [[42]]); //=> true
|
|
*/
|
|
var contains = _curry2(_contains);
|
|
|
|
/**
|
|
* Accepts at least three functions and returns a new function. When invoked, this new
|
|
* function will invoke the first function, `after`, passing as its arguments the
|
|
* results of invoking the subsequent functions with whatever arguments are passed to
|
|
* the new function.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (x1 -> x2 -> ... -> z) -> ((a -> b -> ... -> x1), (a -> b -> ... -> x2), ...) -> (a -> b -> ... -> z)
|
|
* @param {Function} after A function. `after` will be invoked with the return values of
|
|
* `fn1` and `fn2` as its arguments.
|
|
* @param {...Function} functions A variable number of functions.
|
|
* @return {Function} A new function.
|
|
* @example
|
|
*
|
|
* var add = function(a, b) { return a + b; };
|
|
* var multiply = function(a, b) { return a * b; };
|
|
* var subtract = function(a, b) { return a - b; };
|
|
*
|
|
* //≅ multiply( add(1, 2), subtract(1, 2) );
|
|
* R.converge(multiply, add, subtract)(1, 2); //=> -3
|
|
*
|
|
* var add3 = function(a, b, c) { return a + b + c; };
|
|
* R.converge(add3, multiply, add, subtract)(1, 2); //=> 4
|
|
*/
|
|
var converge = curryN(3, function (after) {
|
|
var fns = _slice(arguments, 1);
|
|
return curryN(max(pluck('length', fns)), function () {
|
|
var args = arguments;
|
|
var context = this;
|
|
return after.apply(context, _map(function (fn) {
|
|
return fn.apply(context, args);
|
|
}, fns));
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Finds the set (i.e. no duplicates) of all elements in the first list not contained in the second list.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig [a] -> [a] -> [a]
|
|
* @param {Array} list1 The first list.
|
|
* @param {Array} list2 The second list.
|
|
* @return {Array} The elements in `list1` that are not in `list2`.
|
|
* @see R.differenceWith
|
|
* @example
|
|
*
|
|
* R.difference([1,2,3,4], [7,6,5,4,3]); //=> [1,2]
|
|
* R.difference([7,6,5,4,3], [1,2,3,4]); //=> [7,6,5]
|
|
*/
|
|
var difference = _curry2(function difference(first, second) {
|
|
var out = [];
|
|
var idx = 0;
|
|
var firstLen = first.length;
|
|
while (idx < firstLen) {
|
|
if (!_contains(first[idx], second) && !_contains(first[idx], out)) {
|
|
out[out.length] = first[idx];
|
|
}
|
|
idx += 1;
|
|
}
|
|
return out;
|
|
});
|
|
|
|
/**
|
|
* Returns a new list without any consecutively repeating elements.
|
|
* `R.equals` is used to determine equality.
|
|
*
|
|
* Acts as a transducer if a transformer is given in list position.
|
|
* @see R.transduce
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category List
|
|
* @sig [a] -> [a]
|
|
* @param {Array} list The array to consider.
|
|
* @return {Array} `list` without repeating elements.
|
|
* @example
|
|
*
|
|
* R.dropRepeats([1, 1, 1, 2, 3, 4, 4, 2, 2]); //=> [1, 2, 3, 4, 2]
|
|
*/
|
|
var dropRepeats = _curry1(_dispatchable('dropRepeats', _xdropRepeatsWith(equals), dropRepeatsWith(equals)));
|
|
|
|
/**
|
|
* Combines two lists into a set (i.e. no duplicates) composed of those elements common to both lists.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Relation
|
|
* @sig [a] -> [a] -> [a]
|
|
* @param {Array} list1 The first list.
|
|
* @param {Array} list2 The second list.
|
|
* @see R.intersectionWith
|
|
* @return {Array} The list of elements found in both `list1` and `list2`.
|
|
* @example
|
|
*
|
|
* R.intersection([1,2,3,4], [7,6,5,4,3]); //=> [4, 3]
|
|
*/
|
|
var intersection = _curry2(function intersection(list1, list2) {
|
|
return uniq(_filter(flip(_contains)(list1), list2));
|
|
});
|
|
|
|
/**
|
|
* "lifts" a function of arity > 1 so that it may "map over" an Array or
|
|
* other Functor.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @see R.liftN
|
|
* @category Function
|
|
* @sig (*... -> *) -> ([*]... -> [*])
|
|
* @param {Function} fn The function to lift into higher context
|
|
* @return {Function} The function `fn` applicable to mappable objects.
|
|
* @example
|
|
*
|
|
* var madd3 = R.lift(R.curry(function(a, b, c) {
|
|
* return a + b + c;
|
|
* }));
|
|
* madd3([1,2,3], [1,2,3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7]
|
|
*
|
|
* var madd5 = R.lift(R.curry(function(a, b, c, d, e) {
|
|
* return a + b + c + d + e;
|
|
* }));
|
|
* madd5([1,2], [3], [4, 5], [6], [7, 8]); //=> [21, 22, 22, 23, 22, 23, 23, 24]
|
|
*/
|
|
var lift = _curry1(function lift(fn) {
|
|
return liftN(fn.length, fn);
|
|
});
|
|
|
|
/**
|
|
* Creates a new function that, when invoked, caches the result of calling `fn` for a given
|
|
* argument set and returns the result. Subsequent calls to the memoized `fn` with the same
|
|
* argument set will not result in an additional call to `fn`; instead, the cached result
|
|
* for that set of arguments will be returned.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (*... -> a) -> (*... -> a)
|
|
* @param {Function} fn The function to memoize.
|
|
* @return {Function} Memoized version of `fn`.
|
|
* @example
|
|
*
|
|
* var count = 0;
|
|
* var factorial = R.memoize(function(n) {
|
|
* count += 1;
|
|
* return R.product(R.range(1, n + 1));
|
|
* });
|
|
* factorial(5); //=> 120
|
|
* factorial(5); //=> 120
|
|
* factorial(5); //=> 120
|
|
* count; //=> 1
|
|
*/
|
|
var memoize = _curry1(function memoize(fn) {
|
|
var cache = {};
|
|
return function () {
|
|
var key = toString(arguments);
|
|
if (!_has(key, cache)) {
|
|
cache[key] = fn.apply(this, arguments);
|
|
}
|
|
return cache[key];
|
|
};
|
|
});
|
|
|
|
/**
|
|
* Reasonable analog to SQL `select` statement.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Object
|
|
* @category Relation
|
|
* @sig [k] -> [{k: v}] -> [{k: v}]
|
|
* @param {Array} props The property names to project
|
|
* @param {Array} objs The objects to query
|
|
* @return {Array} An array of objects with just the `props` properties.
|
|
* @example
|
|
*
|
|
* var abby = {name: 'Abby', age: 7, hair: 'blond', grade: 2};
|
|
* var fred = {name: 'Fred', age: 12, hair: 'brown', grade: 7};
|
|
* var kids = [abby, fred];
|
|
* R.project(['name', 'grade'], kids); //=> [{name: 'Abby', grade: 2}, {name: 'Fred', grade: 7}]
|
|
*/
|
|
// passing `identity` gives correct arity
|
|
var project = useWith(_map, pickAll, identity);
|
|
|
|
/**
|
|
* Wraps a constructor function inside a curried function that can be called with the same
|
|
* arguments and returns the same type.
|
|
*
|
|
* @func
|
|
* @memberOf R
|
|
* @category Function
|
|
* @sig (* -> {*}) -> (* -> {*})
|
|
* @param {Function} Fn The constructor function to wrap.
|
|
* @return {Function} A wrapped, curried constructor function.
|
|
* @example
|
|
*
|
|
* // Constructor function
|
|
* var Widget = function(config) {
|
|
* // ...
|
|
* };
|
|
* Widget.prototype = {
|
|
* // ...
|
|
* };
|
|
* var allConfigs = [
|
|
* // ...
|
|
* ];
|
|
* R.map(R.construct(Widget), allConfigs); // a list of Widgets
|
|
*/
|
|
var construct = _curry1(function construct(Fn) {
|
|
return constructN(Fn.length, Fn);
|
|
});
|
|
|
|
var R = {
|
|
F: F,
|
|
T: T,
|
|
__: __,
|
|
add: add,
|
|
addIndex: addIndex,
|
|
adjust: adjust,
|
|
all: all,
|
|
allPass: allPass,
|
|
always: always,
|
|
and: and,
|
|
any: any,
|
|
anyPass: anyPass,
|
|
ap: ap,
|
|
aperture: aperture,
|
|
append: append,
|
|
apply: apply,
|
|
arity: arity,
|
|
assoc: assoc,
|
|
assocPath: assocPath,
|
|
binary: binary,
|
|
bind: bind,
|
|
both: both,
|
|
call: call,
|
|
chain: chain,
|
|
clone: clone,
|
|
commute: commute,
|
|
commuteMap: commuteMap,
|
|
comparator: comparator,
|
|
complement: complement,
|
|
compose: compose,
|
|
composeL: composeL,
|
|
composeP: composeP,
|
|
concat: concat,
|
|
cond: cond,
|
|
construct: construct,
|
|
constructN: constructN,
|
|
contains: contains,
|
|
containsWith: containsWith,
|
|
converge: converge,
|
|
countBy: countBy,
|
|
createMapEntry: createMapEntry,
|
|
curry: curry,
|
|
curryN: curryN,
|
|
dec: dec,
|
|
defaultTo: defaultTo,
|
|
difference: difference,
|
|
differenceWith: differenceWith,
|
|
dissoc: dissoc,
|
|
dissocPath: dissocPath,
|
|
divide: divide,
|
|
drop: drop,
|
|
dropRepeats: dropRepeats,
|
|
dropRepeatsWith: dropRepeatsWith,
|
|
dropWhile: dropWhile,
|
|
either: either,
|
|
empty: empty,
|
|
eq: eq,
|
|
eqDeep: eqDeep,
|
|
eqProps: eqProps,
|
|
equals: equals,
|
|
evolve: evolve,
|
|
filter: filter,
|
|
filterIndexed: filterIndexed,
|
|
find: find,
|
|
findIndex: findIndex,
|
|
findLast: findLast,
|
|
findLastIndex: findLastIndex,
|
|
flatten: flatten,
|
|
flip: flip,
|
|
forEach: forEach,
|
|
forEachIndexed: forEachIndexed,
|
|
fromPairs: fromPairs,
|
|
functions: functions,
|
|
functionsIn: functionsIn,
|
|
groupBy: groupBy,
|
|
gt: gt,
|
|
gte: gte,
|
|
has: has,
|
|
hasIn: hasIn,
|
|
head: head,
|
|
identical: identical,
|
|
identity: identity,
|
|
ifElse: ifElse,
|
|
inc: inc,
|
|
indexOf: indexOf,
|
|
init: init,
|
|
insert: insert,
|
|
insertAll: insertAll,
|
|
intersection: intersection,
|
|
intersectionWith: intersectionWith,
|
|
intersperse: intersperse,
|
|
into: into,
|
|
invert: invert,
|
|
invertObj: invertObj,
|
|
invoke: invoke,
|
|
invoker: invoker,
|
|
is: is,
|
|
isArrayLike: isArrayLike,
|
|
isEmpty: isEmpty,
|
|
isNil: isNil,
|
|
isSet: isSet,
|
|
join: join,
|
|
keys: keys,
|
|
keysIn: keysIn,
|
|
last: last,
|
|
lastIndexOf: lastIndexOf,
|
|
length: length,
|
|
lens: lens,
|
|
lensIndex: lensIndex,
|
|
lensOn: lensOn,
|
|
lensProp: lensProp,
|
|
lift: lift,
|
|
liftN: liftN,
|
|
lt: lt,
|
|
lte: lte,
|
|
map: map,
|
|
mapAccum: mapAccum,
|
|
mapAccumRight: mapAccumRight,
|
|
mapIndexed: mapIndexed,
|
|
mapObj: mapObj,
|
|
mapObjIndexed: mapObjIndexed,
|
|
match: match,
|
|
mathMod: mathMod,
|
|
max: max,
|
|
maxBy: maxBy,
|
|
mean: mean,
|
|
median: median,
|
|
memoize: memoize,
|
|
merge: merge,
|
|
mergeAll: mergeAll,
|
|
min: min,
|
|
minBy: minBy,
|
|
modulo: modulo,
|
|
multiply: multiply,
|
|
nAry: nAry,
|
|
negate: negate,
|
|
none: none,
|
|
not: not,
|
|
nth: nth,
|
|
nthArg: nthArg,
|
|
nthChar: nthChar,
|
|
nthCharCode: nthCharCode,
|
|
of: of,
|
|
omit: omit,
|
|
once: once,
|
|
or: or,
|
|
partial: partial,
|
|
partialRight: partialRight,
|
|
partition: partition,
|
|
path: path,
|
|
pathEq: pathEq,
|
|
pick: pick,
|
|
pickAll: pickAll,
|
|
pickBy: pickBy,
|
|
pipe: pipe,
|
|
pipeL: pipeL,
|
|
pipeP: pipeP,
|
|
pluck: pluck,
|
|
prepend: prepend,
|
|
product: product,
|
|
project: project,
|
|
prop: prop,
|
|
propEq: propEq,
|
|
propOr: propOr,
|
|
props: props,
|
|
range: range,
|
|
reduce: reduce,
|
|
reduceIndexed: reduceIndexed,
|
|
reduceRight: reduceRight,
|
|
reduceRightIndexed: reduceRightIndexed,
|
|
reduced: reduced,
|
|
reject: reject,
|
|
rejectIndexed: rejectIndexed,
|
|
remove: remove,
|
|
repeat: repeat,
|
|
replace: replace,
|
|
reverse: reverse,
|
|
scan: scan,
|
|
slice: slice,
|
|
sort: sort,
|
|
sortBy: sortBy,
|
|
split: split,
|
|
strIndexOf: strIndexOf,
|
|
strLastIndexOf: strLastIndexOf,
|
|
substring: substring,
|
|
substringFrom: substringFrom,
|
|
substringTo: substringTo,
|
|
subtract: subtract,
|
|
sum: sum,
|
|
tail: tail,
|
|
take: take,
|
|
takeWhile: takeWhile,
|
|
tap: tap,
|
|
test: test,
|
|
times: times,
|
|
toLower: toLower,
|
|
toPairs: toPairs,
|
|
toPairsIn: toPairsIn,
|
|
toString: toString,
|
|
toUpper: toUpper,
|
|
transduce: transduce,
|
|
trim: trim,
|
|
type: type,
|
|
unapply: unapply,
|
|
unary: unary,
|
|
uncurryN: uncurryN,
|
|
unfold: unfold,
|
|
union: union,
|
|
unionWith: unionWith,
|
|
uniq: uniq,
|
|
uniqWith: uniqWith,
|
|
unnest: unnest,
|
|
update: update,
|
|
useWith: useWith,
|
|
values: values,
|
|
valuesIn: valuesIn,
|
|
where: where,
|
|
whereEq: whereEq,
|
|
wrap: wrap,
|
|
xprod: xprod,
|
|
zip: zip,
|
|
zipObj: zipObj,
|
|
zipWith: zipWith
|
|
};
|
|
|
|
/* TEST_ENTRY_POINT */
|
|
|
|
if (typeof exports === 'object') {
|
|
module.exports = R;
|
|
} else if (typeof define === 'function' && define.amd) {
|
|
define(function() { return R; });
|
|
} else {
|
|
this.R = R;
|
|
}
|
|
|
|
}.call(this));
|