// 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 . */ 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. * No lists have been harmed in the application of this function. * * @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. * No lists have been harmed in the application of this function. * * @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. * No lists have been harmed in the application of this function. * * @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 ? '' : _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));