From 222653140c392cbbfe1ebb11692c1a6549671813 Mon Sep 17 00:00:00 2001 From: Andrea Scartabelli Date: Fri, 9 Mar 2018 09:33:15 +0100 Subject: [PATCH] - Updated doc comments - Updated travis build targets - Updated license --- .travis.yml | 1 + dist/lamb.js | 22 ++++++++++++++++------ dist/lamb.min.js | 4 ++-- dist/lamb.min.js.map | 2 +- license.txt | 2 +- package-lock.json | 2 +- package.json | 2 +- src/accessors.js | 7 ++++--- src/array.js | 8 ++++++++ src/object.js | 2 +- src/privates.js | 1 + 11 files changed, 37 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index ba0b1de..9ff985c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ script: - gulp travis node_js: - "stable" + - "8" - "7" - "6" - "5" diff --git a/dist/lamb.js b/dist/lamb.js index 2cf8348..2334215 100644 --- a/dist/lamb.js +++ b/dist/lamb.js @@ -1,7 +1,7 @@ /** * @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming. * @author Andrea Scartabelli - * @version 0.55.0-alpha.3 + * @version 0.55.0-alpha.4 * @module lamb * @license MIT * @preserve @@ -46,7 +46,7 @@ * @since 0.53.0 * @type String */ - "@@lamb/version": {value: "0.55.0-alpha.3"} + "@@lamb/version": {value: "0.55.0-alpha.4"} }); // prototype shortcuts @@ -1021,6 +1021,7 @@ /** * Sets, or creates, a property in a copy of the provided object to the desired value. + * @private * @param {Object} source * @param {String} key * @param {*} value @@ -3141,9 +3142,9 @@ * @category Array * @see {@link module:lamb.getAt|getAt} * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts. + * @since 0.23.0 * @param {ArrayLike} arrayLike * @param {Number} index - * @since 0.23.0 * @returns {*} */ function getIndex (arrayLike, index) { @@ -3300,7 +3301,8 @@ var last = getAt(-1); /** - * Builds a function that creates a copy of an array-like object with the given + * A curried version of {@link module:lamb.setIndex|setIndex} that builds + * a function that creates a copy of an array-like object with the given * index changed to the desired value.
* If the index is not an integer or if it's out of bounds, the function * will return a copy of the original array.
@@ -3671,7 +3673,7 @@ * {value: 6, year: "2002"} * ]}; * - * var newUser = _.updatePathIn(user, "scores.0.value", increment); + * var newUser = _.updatePathIn(user, "scores.0.value", inc); * // "newUser" holds: * // {id: 1, scores: [ * // {value: 3, year: "2000"}, @@ -3778,6 +3780,8 @@ * * @memberof module:lamb * @category Array + * @see {@link module:lamb.intersection|intersection} + * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy} * @since 0.6.0 * @param {ArrayLike} arrayLike * @param {ArrayLike} other @@ -4024,6 +4028,8 @@ * * @memberof module:lamb * @category Array + * @see {@link module:lamb.difference|difference} + * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy} * @since 0.5.0 * @param {...ArrayLike} arrayLike * @returns {Array} @@ -4384,6 +4390,8 @@ * @category Array * @function * @see {@link module:lamb.unionBy|unionBy} + * @see {@link module:lamb.difference|difference} + * @see {@link module:lamb.intersection|intersection} * @since 0.5.0 * @param {...ArrayLike} arrayLike * @returns {Array} @@ -4406,6 +4414,8 @@ * @memberof module:lamb * @category Array * @see {@link module:lamb.union|union} + * @see {@link module:lamb.difference|difference} + * @see {@link module:lamb.intersection|intersection} * @since 0.51.0 * @param {ListIteratorCallback} iteratee * @returns {Function} @@ -5830,7 +5840,7 @@ * @see {@link module:lamb.mapValues|mapValues} * @since 0.54.0 * @function - * @param {Function} fn + * @param {ObjectIteratorCallback} fn * @returns {Function} */ var mapValuesWith = _curry2(mapValues, true); diff --git a/dist/lamb.min.js b/dist/lamb.min.js index ee9d0cd..2a3b23a 100644 --- a/dist/lamb.min.js +++ b/dist/lamb.min.js @@ -1,10 +1,10 @@ /** * @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming. * @author Andrea Scartabelli - * @version 0.55.0-alpha.3 + * @version 0.55.0-alpha.4 * @module lamb * @license MIT * @preserve */ -!function(n){"use strict";var r=Object.create(null),o={},c=r;Object.defineProperties(r,{"@@lamb/placeholder":{get:function(){return c},set:function(n){c=n}},"@@lamb/version":{value:"0.55.0-alpha.3"}});var t=Object.prototype,e=String.prototype,f=4294967295;function u(){var t=arguments,e=t.length;return e?function(){for(var n=e-1,r=t[n].apply(this,arguments);n--;)r=t[n].call(this,r);return r}:a}var i=Function.bind.bind(Function.call);function a(n){return n}function l(o,a){return function(){if(!Array.isArray(a))return o.apply(this,arguments);for(var n,r=0,t=[],e=a.length,u=0;u>>0!==r&&(r=n.length),e&&1>>0}function H(n){var r=+n;return r!=r?0:r%1==0?r:Math.floor(Math.abs(r))*(r<0?-1:1)}function J(n,r){return-r<=(n=H(n))&&n>1,a=e({value:t,index:o},{value:r[o],index:o});return i-u<=1?a<0?o:o+1:a<0?n(r,t,e,u,o):0===a?o+1:n(r,t,e,o,i)}(t,r,v(M(u)),0,t.length);return t.splice(o,0,r),t},r.sorter=Zr,r.sorterDesc=Ur,r.sortWith=function(){var r=ln.apply(null,arguments);return function(n){return Gr.apply(null,[n].concat(r))}};var Jr=y(Hr),Qr=y(Hr,!0);function Xr(e,u){return function(){for(var n=H(u),r=ln.apply(null,arguments).slice(0,n),t=r.length;t>>0!==r&&(r=n.length),e&&1>>0}function H(n){var r=+n;return r!=r?0:r%1==0?r:Math.floor(Math.abs(r))*(r<0?-1:1)}function J(n,r){return-r<=(n=H(n))&&n>1,a=e({value:t,index:o},{value:r[o],index:o});return i-u<=1?a<0?o:o+1:a<0?n(r,t,e,u,o):0===a?o+1:n(r,t,e,o,i)}(t,r,v(M(u)),0,t.length);return t.splice(o,0,r),t},r.sorter=Zr,r.sorterDesc=Ur,r.sortWith=function(){var r=ln.apply(null,arguments);return function(n){return Gr.apply(null,[n].concat(r))}};var Jr=y(Hr),Qr=y(Hr,!0);function Xr(e,u){return function(){for(var n=H(u),r=ln.apply(null,arguments).slice(0,n),t=r.length;t\n * @version 0.55.0-alpha.3\n * @module lamb\n * @license MIT\n * @preserve\n */\n(function (host) {\n \"use strict\";\n\n var lamb = Object.create(null);\n var _ = {}; // internal placeholder for partial application\n var _placeholder = lamb; // default value for public placeholder\n\n Object.defineProperties(lamb, {\n /**\n * The object used as a placeholder in partial application. Its default value is\n * the lamb object itself.
\n * The property is public so that you can make Lamb use your own placeholder, however\n * you can't change it at will or the partially applied functions you defined before the\n * change won't recognize the former placeholder.\n * @memberof module:lamb\n * @category Special properties\n * @alias @@lamb/placeholder\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.53.0\n * @type Object\n */\n \"@@lamb/placeholder\": {\n get: function () {\n return _placeholder;\n },\n set: function (value) {\n _placeholder = value;\n }\n },\n\n /**\n * The current library version.\n * @memberof module:lamb\n * @category Special properties\n * @alias @@lamb/version\n * @readonly\n * @since 0.53.0\n * @type String\n */\n \"@@lamb/version\": {value: \"0.55.0-alpha.3\"}\n });\n\n // prototype shortcuts\n var _objectProto = Object.prototype;\n var _stringProto = String.prototype;\n\n // constants\n var MAX_ARRAY_LENGTH = 4294967295;\n\n /**\n * Builds a function that returns a constant value.\n * It's actually the simplest form of the K combinator or Kestrel.\n * @example\n * var truth = _.always(true);\n *\n * truth() // => true\n * truth(false) // => true\n * truth(1, 2) // => true\n *\n * // the value being returned is actually the\n * // very same value passed to the function\n * var foo = {bar: \"baz\"};\n * var alwaysFoo = _.always(foo);\n *\n * alwaysFoo() === foo // => true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n function always (value) {\n return function () {\n return value;\n };\n }\n\n /**\n * Returns a function that is the composition of the functions given as parameters.\n * Each function consumes the result of the function that follows.\n * @example\n * var sayHi = function (name) { return \"Hi, \" + name; };\n * var capitalize = function (s) {\n * return s[0].toUpperCase() + s.substr(1).toLowerCase();\n * };\n * var fixNameAndSayHi = _.compose(sayHi, capitalize);\n *\n * sayHi(\"bOb\") // => \"Hi, bOb\"\n * fixNameAndSayHi(\"bOb\") // \"Hi, Bob\"\n *\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, _.getKey(\"name\"));\n *\n * _.map(users, sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.pipe|pipe}\n * @since 0.1.0\n * @param {...Function} fn\n * @returns {Function}\n */\n function compose () {\n var functions = arguments;\n var len = functions.length;\n\n return len ? function () {\n var idx = len - 1;\n var result = functions[idx].apply(this, arguments);\n\n while (idx--) {\n result = functions[idx].call(this, result);\n }\n\n return result;\n } : identity;\n }\n\n /**\n * Creates generic functions out of methods.\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}.\n * Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @memberof module:lamb\n * @category Function\n * @function\n * @example\n * var join = _.generic(Array.prototype.join);\n *\n * join([1, 2, 3, 4, 5], \"-\") // => \"1-2-3-4-5\"\n *\n * // the function will work with any array-like object\n * join(\"hello\", \"-\") // => \"h-e-l-l-o\"\n *\n * @since 0.1.0\n * @param {Function} method\n * @returns {Function}\n */\n var generic = Function.bind.bind(Function.call);\n\n /**\n * The I combinator. Any value passed to the function is simply returned as it is.\n * @example\n * var foo = {bar: \"baz\"};\n *\n * _.identity(foo) === foo // true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {*} The value passed as parameter.\n */\n function identity (value) {\n return value;\n }\n\n /**\n * Builds a partially applied function. The lamb object itself can be\n * used as a placeholder argument and it's useful to alias it with a short symbol\n * such as _.
\n * You can use a custom placeholder by setting the\n * {@link module:lamb.@@lamb/placeholder|@@lamb/placeholder} property.\n * @example\n * var users = [\n * {id: 1, name: \"John\", active: true, confirmedMail: true},\n * {id: 2, name: \"Jane\", active: true, confirmedMail: false},\n * {id: 3, name: \"Mario\", active: false, confirmedMail: false}\n * ];\n * var isKeyTrue = _.partial(_.hasKeyValue, [_, true]);\n * var isActive = isKeyTrue(\"active\");\n * var hasConfirmedMail = isKeyTrue(\"confirmedMail\");\n *\n * _.map(users, isActive) // => [true, true, false]\n * _.map(users, hasConfirmedMail) // => [true, false, false]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.@@lamb/placeholder|@@lamb/placeholder}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Array} args\n * @returns {Function}\n */\n function partial (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = 0;\n var newArgs = [];\n var argsLen = args.length;\n\n for (var i = 0, boundArg; i < argsLen; i++) {\n boundArg = args[i];\n newArgs[i] = _isPlaceholder(boundArg) ? arguments[lastIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastIdx < len; lastIdx++) {\n newArgs[i++] = arguments[lastIdx];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Like {@link module:lamb.partial|partial} will build a partially applied function and\n * it will accept placeholders.
\n * The difference is that the bound arguments will be appended to the ones received by\n * the resulting function.\n * @example\n * Explaining the difference with partial:\n * var f1 = _.partial(_.list, [\"a\", \"b\", \"c\"]);\n * var f2 = _.partialRight(_.list, [\"a\", \"b\", \"c\"]);\n *\n * f1(\"d\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"d\", \"e\") // => [\"d\", \"e\", \"a\", \"b\", \"c\"]\n *\n * @example\n * Explaining placeholder substitutions:\n * var f1 = _.partial(_.list, [\"a\", _, _, \"d\"]);\n * var f2 = _.partialRight(_.list, [\"a\", _, _, \"d\"]);\n *\n * f1(\"b\", \"c\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"b\", \"c\", \"e\") // => [\"b\", \"a\", \"c\", \"e\", \"d\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.@@lamb/placeholder|@@lamb/placeholder}\n * @param {Function} fn\n * @param {Array} args\n * @since 0.52.0\n * @returns {Function}\n */\n function partialRight (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = arguments.length - 1;\n var argsLen = args.length;\n var boundArgs = Array(argsLen);\n var newArgs = [];\n\n for (var i = argsLen - 1, boundArg; i > -1; i--) {\n boundArg = args[i];\n boundArgs[i] = _isPlaceholder(boundArg) ? arguments[lastIdx--] : boundArg;\n }\n\n for (i = 0; i <= lastIdx; i++) {\n newArgs[i] = arguments[i];\n }\n\n for (var j = 0; j < argsLen; j++) {\n newArgs[i++] = boundArgs[j];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n lamb.always = always;\n lamb.compose = compose;\n lamb.generic = generic;\n lamb.identity = identity;\n lamb.partial = partial;\n lamb.partialRight = partialRight;\n\n /**\n * Builds an array with the received arguments excluding the first one.
\n * To be used with the arguments object, which needs to be passed to the apply\n * method of this function.\n * @private\n * @function\n * @param {...*} value\n * @returns {Array}\n */\n var _argsTail = _argsToArrayFrom(1);\n\n /**\n * Builds helper functions to extract portions of the arguments\n * object rather efficiently without having to write for loops\n * manually for each case.
\n * The arguments object needs to be passed to the apply method\n * of the generated function.\n * @private\n * @param {Number} idx\n * @returns {Function}\n */\n function _argsToArrayFrom (idx) {\n return function () {\n var argsLen = arguments.length || idx;\n var len = argsLen - idx;\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = arguments[i + idx];\n }\n\n return result;\n };\n }\n\n /**\n * Keeps building a partial application of the received function as long\n * as it's called with placeholders; applies the original function to\n * the collected parameters otherwise.
\n * The function checks only the public placeholder to gain a little performance\n * as no function in Lamb is built with {@link module:lamb.asPartial|asPartial}.\n * @private\n * @param {Function} fn\n * @param {Array} argsHolder\n * @returns {Function|*}\n */\n function _asPartial (fn, argsHolder) {\n return function () {\n var argsLen = arguments.length;\n var lastIdx = 0;\n var newArgs = [];\n\n for (var i = 0, len = argsHolder.length, boundArg; i < len; i++) {\n boundArg = argsHolder[i];\n newArgs[i] = boundArg === _placeholder && lastIdx < argsLen ? arguments[lastIdx++] : boundArg;\n }\n\n while (lastIdx < argsLen) {\n newArgs[i++] = arguments[lastIdx++];\n }\n\n for (i = 0; i < argsLen; i++) {\n if (arguments[i] === _placeholder) {\n return _asPartial(fn, newArgs);\n }\n }\n\n for (i = 0, len = newArgs.length; i < len; i++) {\n if (newArgs[i] === _placeholder) {\n newArgs[i] = void 0;\n }\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * The default comparer for sorting functions.
\n * If the given values are of different types they\n * will be both converted to strings.
\n * Uses the SameValueZero comparison.\n * @private\n * @param {*} a\n * @param {*} b\n * @returns {Number} -1 | 0 | 1\n */\n function _comparer (a, b) {\n var result = 0;\n\n if (typeof a !== typeof b) {\n a = String(a);\n b = String(b);\n }\n\n /* eslint-disable no-self-compare */\n\n if (!areSVZ(a, b)) {\n if (a > b || a !== a) {\n result = 1;\n } else if (a < b || b !== b) {\n result = -1;\n }\n }\n\n /* eslint-enable no-self-compare */\n\n return result;\n }\n\n /**\n * Accepts a list of sorting criteria with at least one element\n * and builds a function that compares two values with such criteria.\n * @private\n * @param {Sorter[]} criteria\n * @returns {Function}\n */\n function _compareWith (criteria) {\n return function (a, b) {\n var len = criteria.length;\n var criterion = criteria[0];\n var result = criterion.compare(a.value, b.value);\n\n for (var i = 1; result === 0 && i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n }\n\n if (result === 0) {\n result = a.index - b.index;\n }\n\n return criterion.isDescending ? -result : result;\n };\n }\n\n /**\n * Used by curry functions to collect arguments until the arity is consumed,\n * then applies the original function.\n * @private\n * @param {Function} fn\n * @param {Number} arity\n * @param {Boolean} isRightCurry\n * @param {Boolean} isAutoCurry\n * @param {Array} argsHolder\n * @returns {Function}\n */\n function _currier (fn, arity, isRightCurry, isAutoCurry, argsHolder) {\n return function () {\n var holderLen = argsHolder.length;\n var argsLen = arguments.length;\n var newArgsLen = holderLen + (argsLen > 1 && isAutoCurry ? argsLen : 1);\n var newArgs = Array(newArgsLen);\n\n for (var i = 0; i < holderLen; i++) {\n newArgs[i] = argsHolder[i];\n }\n\n for (; i < newArgsLen; i++) {\n newArgs[i] = arguments[i - holderLen];\n }\n\n if (newArgsLen >= arity) {\n return fn.apply(this, isRightCurry ? newArgs.reverse() : newArgs);\n } else {\n return _currier(fn, arity, isRightCurry, isAutoCurry, newArgs);\n }\n };\n }\n\n /**\n * Prepares a function for currying. If it's not auto-currying and the arity\n * is 2 or 3 returns optimized functions, otherwise delegates the currying\n * to the _currier function.
\n * If the desumed arity isn't greater than one, it will return the received\n * function itself, instead.\n * @private\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @param {Boolean} [isRightCurry=false]\n * @param {Boolean} [isAutoCurry=false]\n * @returns {Function}\n */\n function _curry (fn, arity, isRightCurry, isAutoCurry) {\n if (arity >>> 0 !== arity) {\n arity = fn.length;\n }\n\n if (isAutoCurry && arity > 1 || arity > 3) {\n return _currier(fn, arity, isRightCurry, isAutoCurry, []);\n } else if (arity === 2) {\n return _curry2(fn, isRightCurry);\n } else if (arity === 3) {\n return _curry3(fn, isRightCurry);\n } else {\n return fn;\n }\n }\n\n /**\n * Curries a function of arity 2.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry2 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return isRightCurry ? fn.call(this, b, a) : fn.call(this, a, b);\n };\n };\n }\n\n /**\n * Curries a function of arity 3.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry3 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return function (c) {\n return isRightCurry ? fn.call(this, c, b, a) : fn.call(this, a, b, c);\n };\n };\n };\n }\n\n /**\n * Flattens an array.\n * @private\n * @param {Array} array - The source array\n * @param {Boolean} isDeep - Whether to perform a deep flattening or not\n * @param {Array} output - An array to collect the result\n * @param {Number} idx - The next index to be filled in the output\n * @returns {Array} The output array filled with the results\n */\n function _flatten (array, isDeep, output, idx) {\n for (var i = 0, len = array.length, value, j, vLen; i < len; i++) {\n value = array[i];\n\n if (!Array.isArray(value)) {\n output[idx++] = value;\n } else if (isDeep) {\n _flatten(value, true, output, idx);\n idx = output.length;\n } else {\n vLen = value.length;\n output.length += vLen;\n\n for (j = 0; j < vLen; j++) {\n output[idx++] = value[j];\n }\n }\n }\n\n return output;\n }\n\n /**\n * Converts a value to a number and returns it if it's not NaN, otherwise\n * returns zero.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _forceToNumber (value) {\n var n = +value;\n\n return n === n ? n : 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * Establishes at which index an element should be inserted in a sorted array to respect\n * the array order. Needs the comparer used to sort the array.\n * @private\n * @param {Array} array\n * @param {*} element\n * @param {Function} comparer\n * @param {Number} start\n * @param {Number} end\n * @returns {Number}\n */\n function _getInsertionIndex (array, element, comparer, start, end) {\n if (array.length === 0) {\n return 0;\n }\n\n var pivot = (start + end) >> 1;\n var result = comparer(\n {value: element, index: pivot},\n {value: array[pivot], index: pivot}\n );\n\n if (end - start <= 1) {\n return result < 0 ? pivot : pivot + 1;\n } else if (result < 0) {\n return _getInsertionIndex(array, element, comparer, start, pivot);\n } else if (result === 0) {\n return pivot + 1;\n } else {\n return _getInsertionIndex(array, element, comparer, pivot, end);\n }\n }\n\n /**\n * Gets the number of consecutive elements satisfying a predicate in an array-like object.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function _getNumConsecutiveHits (arrayLike, predicate) {\n var idx = 0;\n var len = arrayLike.length;\n\n while (idx < len && predicate(arrayLike[idx], idx, arrayLike)) {\n idx++;\n }\n\n return idx;\n }\n\n /**\n * Builds the prefix or suffix to be used when padding a string.\n * @private\n * @param {String} source\n * @param {String} char\n * @param {Number} len\n * @returns {String}\n */\n function _getPadding (source, char, len) {\n if (!isNil(source) && type(source) !== \"String\") {\n source = String(source);\n }\n\n return _repeat(String(char)[0] || \"\", Math.ceil(len - source.length));\n }\n\n /**\n * Checks if a path is valid in the given object and retrieves the path target.\n * @private\n * @param {Object} obj\n * @param {String[]} parts\n * @param {Boolean} walkNonEnumerables\n * @returns {Object}\n */\n function _getPathInfo (obj, parts, walkNonEnumerables) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n var target = obj;\n var i = -1;\n var len = parts.length;\n var key;\n\n while (++i < len) {\n key = _getPathKey(target, parts[i], walkNonEnumerables);\n\n if (isUndefined(key)) {\n break;\n }\n\n target = target[key];\n }\n\n return i === len ? {isValid: true, target: target} : {isValid: false, target: void 0};\n }\n\n /**\n * Helper to retrieve the correct key while evaluating a path.\n * @private\n * @param {Object} target\n * @param {String} key\n * @param {Boolean} includeNonEnumerables\n * @returns {String|Number|Undefined}\n */\n function _getPathKey (target, key, includeNonEnumerables) {\n if (includeNonEnumerables && key in Object(target) || _isEnumerable(target, key)) {\n return key;\n }\n\n var n = +key;\n var len = target && target.length;\n\n return n >= -len && n < len ? n < 0 ? n + len : n : void 0;\n }\n\n /**\n * Builds a \"grouping function\" for an array-like object.\n * @private\n * @param {Function} makeValue\n * @returns {Function}\n */\n function _groupWith (makeValue) {\n return function (arrayLike, iteratee) {\n var result = {};\n var len = arrayLike.length;\n\n for (var i = 0, element, key; i < len; i++) {\n element = arrayLike[i];\n key = iteratee(element, i, arrayLike);\n result[key] = makeValue(result[key], element);\n }\n\n return result;\n };\n }\n\n /**\n * Makes an object immutable by recursively calling Object.freeze\n * on its members.\n * @private\n * @param {Object} obj\n * @param {Array} seen\n * @returns {Object} The obj parameter itself, not a copy.\n */\n function _immutable (obj, seen) {\n if (seen.indexOf(obj) === -1) {\n seen.push(Object.freeze(obj));\n\n forEach(Object.getOwnPropertyNames(obj), function (key) {\n var value = obj[key];\n\n if (typeof value === \"object\" && !isNull(value)) {\n _immutable(value, seen);\n }\n });\n }\n\n return obj;\n }\n\n /**\n * If a method with the given name exists on the target, applies it to the provided\n * arguments and returns the result. Returns undefined otherwise.
\n * The arguments for the method are built by concatenating the array of bound arguments,\n * optionally received by {@link module:lamb.invoker|invoker}, with the final set of, also\n * optional, args.\n * @private\n * @param {Array} boundArgs\n * @param {String} methodName\n * @param {Object} target\n * @param {...*} [args]\n * @returns {*}\n */\n function _invoker (boundArgs, methodName, target) {\n var method = target[methodName];\n\n if (typeof method !== \"function\") {\n return void 0;\n }\n\n var boundArgsLen = boundArgs.length;\n var ofs = 3 - boundArgsLen;\n var len = arguments.length - ofs;\n var args = Array(len);\n\n for (var i = 0; i < boundArgsLen; i++) {\n args[i] = boundArgs[i];\n }\n\n for (; i < len; i++) {\n args[i] = arguments[i + ofs];\n }\n\n return method.apply(target, args);\n }\n\n /**\n * Accepts a target object and a key name and verifies that the target is an array and that\n * the key is an existing index.\n * @private\n * @param {Object} target\n * @param {String|Number} key\n * @returns {Boolean}\n */\n function _isArrayIndex (target, key) {\n var n = +key;\n\n return Array.isArray(target) && n % 1 === 0 && !(n < 0 && _isEnumerable(target, key));\n }\n\n /**\n * Checks whether the specified key is an enumerable property of the given object or not.\n * @private\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function _isEnumerable (obj, key) {\n return key in Object(obj) && (_isOwnEnumerable(obj, key) || ~_safeEnumerables(obj).indexOf(key));\n }\n\n /**\n * Checks whether the specified key is a own enumerable property of the given object or not.\n * @private\n * @function\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var _isOwnEnumerable = generic(_objectProto.propertyIsEnumerable);\n\n /**\n * Checks whether the given value is the internal or the public placeholder.\n * @private\n * @param {*} value\n * @returns {Boolean}\n */\n function _isPlaceholder (value) {\n return value === _ || value === _placeholder;\n }\n\n /**\n * Accepts an object and build a function expecting a key to create a \"pair\" with the key\n * and its value.\n * @private\n * @function\n * @param {Object} obj\n * @returns {Function}\n */\n var _keyToPairIn = _curry2(function (obj, key) {\n return [key, obj[key]];\n });\n\n /**\n * Helper to build the {@link module:lamb.everyIn|everyIn} or the\n * {@link module:lamb.someIn|someIn} function.\n * @private\n * @param {Boolean} defaultResult\n * @returns {Function}\n */\n function _makeArrayChecker (defaultResult) {\n return function (arrayLike, predicate) {\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (defaultResult ^ !!predicate(arrayLike[i], i, arrayLike)) {\n return !defaultResult;\n }\n }\n\n return defaultResult;\n };\n }\n\n /**\n * Helper to build the {@link module:lamb.flatten|flatten} and\n * {@link module:lamb.shallowFlatten|shallowFlatten} functions.\n * @private\n * @function\n * @param {Boolean} isDeep\n * @returns {Function}\n */\n var _makeArrayFlattener = _curry2(function (isDeep, array) {\n return Array.isArray(array) ? _flatten(array, isDeep, [], 0) : slice(array, 0, array.length);\n });\n\n /**\n * Builds a list of sorting criteria from a list of sorter functions. Returns a list containing\n * a single default sorting criterion if the sorter list is empty.\n * @private\n * @param {Function[]} sorters\n * @returns {Sorter[]}\n */\n function _makeCriteria (sorters) {\n return sorters.length ? map(sorters, _makeCriterion) : [_sorter()];\n }\n\n /**\n * Converts a sorting function to a sorting criterion if necessary.\n * @private\n * @param {Function} criterion\n * @returns {Sorter}\n */\n function _makeCriterion (criterion) {\n return criterion && typeof criterion.compare === \"function\" ? criterion : _sorter(criterion);\n }\n\n /**\n * Builds a partial application of a ternary function so that its first parameter\n * is expected as the last one.
\n * The shouldAritize parameter is for the \"reduce\" functions, where\n * the absence of the initialValue transforms a \"fold\" operation into a\n * \"reduce\" one.\n * @private\n * @param {Function} fn\n * @param {Boolean} shouldAritize\n * @returns {Function}\n */\n function _makePartial3 (fn, shouldAritize) {\n return function (a, b) {\n var f = shouldAritize && arguments.length !== 2 ? binary(fn) : fn;\n\n return partial(f, [_, a, b]);\n };\n }\n\n /**\n * Builds a reduce function. The step parameter must be 1\n * to build {@link module:lamb.reduce|reduce} and -1 to build\n * {@link module:lamb.reduceRight|reduceRight}.\n * @private\n * @param {Number} step\n * @returns {Function}\n */\n function _makeReducer (step) {\n return function (arrayLike, accumulator, initialValue) {\n var len = _toArrayLength(arrayLike.length);\n var idx = step === 1 ? 0 : len - 1;\n var nCalls;\n var result;\n\n if (arguments.length === 3) {\n nCalls = len;\n result = initialValue;\n } else {\n if (len === 0) {\n throw new TypeError(\"Reduce of empty array-like with no initial value\");\n }\n\n result = arrayLike[idx];\n idx += step;\n nCalls = len - 1;\n }\n\n for (; nCalls--; idx += step) {\n result = accumulator(result, arrayLike[idx], idx, arrayLike);\n }\n\n return result;\n };\n }\n\n /**\n * Builds a TypeError stating that it's not possible to convert the given value to the\n * desired type.\n * @private\n * @param {*} value\n * @param {String} desiredType\n * @returns {TypeError}\n */\n function _makeTypeErrorFor (value, desiredType) {\n return new TypeError(\"Cannot convert \" + type(value).toLowerCase() + \" to \" + desiredType);\n }\n\n /**\n * Merges the received objects using the provided function to retrieve their keys.\n * @private\n * @param {Function} getKeys\n * @param {...Object} source\n * @returns {Object}\n */\n function _merge (getKeys) {\n return reduce(_argsTail.apply(null, arguments), function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n }\n\n /**\n * Using the provided function to retrieve the keys, builds a new function\n * expecting an object to create a list of key / value pairs.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _pairsFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), _keyToPairIn(obj));\n });\n\n /**\n * A null-safe function to repeat the source string the desired amount of times.\n * @private\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function _repeat (source, times) {\n var result = \"\";\n\n for (var i = 0; i < times; i++) {\n result += source;\n }\n\n return result;\n }\n\n /**\n * Builds a list of the enumerable properties of an object.\n * The function is null-safe, unlike the public one.\n * @private\n * @param {Object} obj\n * @returns {String[]}\n */\n function _safeEnumerables (obj) {\n var result = [];\n\n for (var key in obj) {\n result.push(key);\n }\n\n return result;\n }\n\n /**\n * A null-safe version of Object.keys.\n * @private\n * @function\n * @param {Object} obj\n * @returns {String[]}\n */\n var _safeKeys = compose(Object.keys, Object);\n\n /**\n * A generic version of String.prototype.search\n * @private\n * @function\n * @param {String} s\n * @param {RegExp} pattern\n * @return {Number}\n */\n var _search = generic(_stringProto.search);\n\n /**\n * Sets, or creates, a property in a copy of the provided object to the desired value.\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function _setIn (source, key, value) {\n var result = {};\n\n for (var prop in source) {\n result[prop] = source[prop];\n }\n\n result[key] = value;\n\n return result;\n }\n\n /**\n * Sets an index in an array-like object.
\n * If provided with an updater function it will use it to update the current value,\n * otherwise sets the index to the specified value.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {Number} idx\n * @param {*} [value]\n * @param {Function} [updater]\n * @returns {Array}\n */\n function _setIndex (arrayLike, idx, value, updater) {\n var result = slice(arrayLike, 0, arrayLike.length);\n var n = _toNaturalIndex(idx, result.length);\n\n if (n === n) { // eslint-disable-line no-self-compare\n result[n] = arguments.length === 4 ? updater(arrayLike[n]) : value;\n }\n\n return result;\n }\n\n /**\n * Sets the object's property targeted by the given path to the desired value.
\n * Works with arrays and is able to set their indexes, even negative ones.\n * @private\n * @param {Object|Array} obj\n * @param {String[]} parts\n * @param {*} value\n * @returns {Object|Array}\n */\n function _setPathIn (obj, parts, value) {\n var key = parts[0];\n var partsLen = parts.length;\n var v;\n\n if (partsLen === 1) {\n v = value;\n } else {\n var targetKey = _getPathKey(obj, key, false);\n\n v = _setPathIn(\n isUndefined(targetKey) ? targetKey : obj[targetKey],\n slice(parts, 1, partsLen),\n value\n );\n }\n\n return _isArrayIndex(obj, key) ? _setIndex(obj, key, v) : _setIn(obj, key, v);\n }\n\n /**\n * Builds a sorting criterion. If the comparer function is missing, the default\n * comparer will be used instead.\n * @private\n * @param {Function} reader\n * @param {Boolean} isDescending\n * @param {Function} [comparer]\n * @returns {Sorter}\n */\n function _sorter (reader, isDescending, comparer) {\n if (typeof reader !== \"function\" || reader === identity) {\n reader = null;\n }\n\n if (typeof comparer !== \"function\") {\n comparer = _comparer;\n }\n\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (reader) {\n a = reader(a);\n b = reader(b);\n }\n\n return comparer(a, b);\n }\n };\n }\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create an array containing a list\n * of the keys in its first index and the corresponding list of values\n * in the second one.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _tearFrom = _curry2(function (getKeys, obj) {\n return reduce(getKeys(obj), function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n\n return result;\n }, [[], []]);\n });\n\n /**\n * Converts a value to a valid array length, thus an integer within\n * 0 and 232 - 1 (both included).\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toArrayLength (value) {\n return clamp(value, 0, MAX_ARRAY_LENGTH) >>> 0;\n }\n\n /**\n * Converts a value to an integer.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toInteger (value) {\n var n = +value;\n\n if (n !== n) { // eslint-disable-line no-self-compare\n return 0;\n } else if (n % 1 === 0) {\n return n;\n } else {\n return Math.floor(Math.abs(n)) * (n < 0 ? -1 : 1);\n }\n }\n\n /**\n * Checks if the given number, even negative, represents an array-like index\n * within the provided length. If so returns its natural number equivalent.
\n * Returns NaN otherwise.\n * @private\n * @param {Number} idx\n * @param {Number} len\n * @returns {Number}\n */\n function _toNaturalIndex (idx, len) {\n idx = _toInteger(idx);\n\n return idx >= -len && idx < len ? idx < 0 ? idx + len : idx : NaN;\n }\n\n /**\n * Splits a sting path using the provided separator and returns an array\n * of path parts.\n * @private\n * @param {String} path\n * @param {String} separator\n * @returns {String[]}\n */\n function _toPathParts (path, separator) {\n return String(path).split(separator || \".\");\n }\n\n /**\n * Creates a non-null-safe version of the provided \"getKeys\" function.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _unsafeKeyListFrom = _curry2(function (getKeys, obj) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n return getKeys(obj);\n });\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create the list of values for such keys.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _valuesFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), partial(getIn, [obj]));\n });\n\n /**\n * Builds a predicate to check if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.isIn|isIn} for an uncurried version.\n * @example\n * var containsNaN = _.contains(NaN);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.isIn|isIn}\n * @since 0.13.0\n * @param {*} value\n * @returns {Function}\n */\n var contains = _curry2(isIn, true);\n\n /**\n * Checks if all the elements in an array-like object satisfy the given predicate.
\n * The function will stop calling the predicate as soon as it returns a falsy value.
\n * Note that an empty array-like will always produce a true result regardless of the\n * predicate because of [vacuous truth]{@link https://en.wikipedia.org/wiki/Vacuous_truth}.
\n * Also note that unlike the native\n * [Array.prototype.every]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: true},\n * {\"name\": \"John\", \"age\": 40, active: true},\n * {\"name\": \"Mario\", \"age\": 17, active: true},\n * {\"name\": \"Paolo\", \"age\": 15, active: true}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.everyIn(persons, isAdult) // => false\n * _.everyIn(persons, isActive) // => true\n *\n * @example Showing the difference with Array.prototype.every:\n * var isDefined = _.not(_.isUndefined);\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.every(isDefined) // => true\n * _.everyIn(arr, isDefined) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.every|every}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var everyIn = _makeArrayChecker(true);\n\n /**\n * A curried version of {@link module:lamb.everyIn|everyIn} that expects a predicate\n * to build a function waiting for the array-like to act upon.\n * @example\n * var data = [2, 3, 5, 6, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var allEvens = _.every(isEven);\n * var allIntegers = _.every(_.isInteger);\n *\n * allEvens(data) // => false\n * allIntegers(data) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.everyIn|everyIn}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var every = _curry2(everyIn, true);\n\n /**\n * Builds an array comprised of all values of the array-like object passing the predicate\n * test.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n *\n * _.filter([\"Foo\", \"bar\", \"baZ\"], isLowerCase) // => [\"bar\"]\n *\n * // the function will work with any array-like object\n * _.filter(\"fooBAR\", isLowerCase) // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.filterWith|filterWith}\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @since 0.1.0\n * @returns {Array}\n */\n function filter (arrayLike, predicate) {\n var len = arrayLike.length;\n var result = [];\n\n for (var i = 0; i < len; i++) {\n predicate(arrayLike[i], i, arrayLike) && result.push(arrayLike[i]);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.filter|filter} that uses the given predicate\n * to build a function expecting the array-like object to act upon.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n * var getLowerCaseEntries = _.filterWith(isLowerCase);\n *\n * getLowerCaseEntries([\"Foo\", \"bar\", \"baZ\"]) // => [\"bar\"]\n *\n * // array-like objects can be used as well\n * getLowerCaseEntries(\"fooBAR\") // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.filter|filter}\n * @since 0.9.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var filterWith = _curry2(filter, true);\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns it if\n * the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.find(persons, _.hasKeyValue(\"age\", 40)) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.find(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\n function find (arrayLike, predicate) {\n var idx = findIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns its\n * index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findIndex(persons, _.hasKeyValue(\"age\", 40)) // => 1\n * _.findIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function findIndex (arrayLike, predicate) {\n var result = -1;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (predicate(arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.findIndex|findIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEvenIdx = _.findIndexWhere(isEven);\n *\n * findEvenIdx([1, 3, 4, 5, 7]) // => 2\n * findEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findIndex|findIndex}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findIndexWhere = _curry2(findIndex, true);\n\n /**\n * A curried version of {@link module:lamb.find|find} expecting the array-like object\n * to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 7]) // => 4\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.find|find}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findWhere = _curry2(find, true);\n\n /**\n * Executes the provided iteratee for each element of the given array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment:\n * var addClass = _.curry(function (className, element) {\n * element.classList.add(className);\n * });\n * var paragraphs = document.querySelectorAll(\"#some-container p\");\n *\n * _.forEach(paragraphs, addClass(\"main\"));\n * // each \"p\" element in the container will have the \"main\" class now\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Undefined}\n */\n function forEach (arrayLike, iteratee) {\n for (var i = 0, len = _toArrayLength(arrayLike.length); i < len; i++) {\n iteratee(arrayLike[i], i, arrayLike);\n }\n }\n\n /**\n * Checks if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.contains|contains} for a curried version building a predicate.\n * @example\n * var numbers = [0, 1, 2, 3, NaN];\n *\n * _.isIn(numbers, 1) // => true\n * _.isIn(numbers, 0) // => true\n * _.isIn(numbers, -0) // => true\n * _.isIn(numbers, NaN) // => true\n * _.isIn(numbers, 5) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.contains|contains}\n * @since 0.13.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Boolean}\n */\n function isIn (arrayLike, value) {\n var result = false;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (areSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Generates an array with the values passed as arguments.
\n * Behaves like ES6's [Array.of]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of}.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.1.0\n * @param {...*} value\n * @returns {Array}\n */\n var list = _argsToArrayFrom(0);\n\n /**\n * Builds a new array by applying the iteratee function to each element of the\n * received array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.map([\"Joe\", \"Mario\", \"Jane\"], _.invoker(\"toUpperCase\")) // => [\"JOE\", \"MARIO\", \"JANE\"]\n *\n * _.map([4, 9, 16], Math.sqrt); // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.mapWith|mapWith}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function map (arrayLike, iteratee) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = iteratee(arrayLike[i], i, arrayLike);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.map|map} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var square = function (n) { return n * n; };\n * var getSquares = _.mapWith(square);\n *\n * getSquares([1, 2, 3, 4, 5]) // => [1, 4, 9, 16, 25]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.map|map}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ListIteratorCallback} iteratee\n * @returns {function}\n */\n var mapWith = _curry2(map, true);\n\n /**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new\n * value using the provided accumulator function.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.reduce([1, 2, 3, 4], _.sum) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRight|reduceRight}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduce = _makeReducer(1);\n\n /**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last\n * element instead.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduce|reduce}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduceRight = _makeReducer(-1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduceRight} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceRightWith(_.sum)(arr) // => 15\n * _.reduceRightWith(_.subtract)(arr) // => -5\n * _.reduceRightWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceWith|reduceWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceRightWith = _makePartial3(reduceRight, true);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduce} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceWith(_.sum)(arr) // => 15\n * _.reduceWith(_.subtract)(arr) // => -13\n * _.reduceWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRightWith|reduceRightWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceWith = _makePartial3(reduce, true);\n\n /**\n * Reverses a copy of the given array-like object.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.reverse(arr) // => [3, 2, 1];\n *\n * // `arr` still is [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.19.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function reverse (arrayLike) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0, ofs = len - 1; i < len; i++) {\n result[i] = arrayLike[ofs - i];\n }\n\n return result;\n }\n\n /**\n * Builds an array by extracting a portion of an array-like object.
\n * Note that unlike the native array method this function ensures that dense\n * arrays are returned.
\n * Also, unlike the native method, the start and end\n * parameters aren't optional and will be simply converted to integer.
\n * See {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.slice(arr, 0, 2) // => [1, 2]\n * _.slice(arr, 2, -1) // => [3, 4]\n * _.slice(arr, -3, 5) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sliceAt|sliceAt}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\n function slice (arrayLike, start, end) {\n var len = _toArrayLength(arrayLike.length);\n var begin = _toInteger(start);\n var upTo = _toInteger(end);\n\n if (begin < 0) {\n begin = begin < -len ? 0 : begin + len;\n }\n\n if (upTo < 0) {\n upTo = upTo < -len ? 0 : upTo + len;\n } else if (upTo > len) {\n upTo = len;\n }\n\n var resultLen = upTo - begin;\n var result = resultLen > 0 ? Array(resultLen) : [];\n\n for (var i = 0; i < resultLen; i++) {\n result[i] = arrayLike[begin + i];\n }\n\n return result;\n }\n\n /**\n * Given the start and end bounds, builds a partial application\n * of {@link module:lamb.slice|slice} expecting the array-like object to slice.
\n * See also {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var s = \"hello\";\n * var dropFirstAndLast = _.sliceAt(1, -1);\n *\n * dropFirstAndLast(arr) // => [2, 3, 4]\n * dropFirstAndLast(s) // => [\"e\", \"l\", \"l\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.slice|slice}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.48.0\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Function}\n */\n var sliceAt = _makePartial3(slice);\n\n /**\n * Checks if at least one element in an array-like object satisfies the given predicate.
\n * The function will stop calling the predicate as soon as it returns a truthy value.
\n * Note that unlike the native\n * [Array.prototype.some]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: false},\n * {\"name\": \"John\", \"age\": 40, active: false},\n * {\"name\": \"Mario\", \"age\": 17, active: false},\n * {\"name\": \"Paolo\", \"age\": 15, active: false}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.someIn(persons, isAdult) // => true\n * _.someIn(persons, isActive) // => false\n *\n * @example Showing the difference with Array.prototype.some:\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.some(_.isUndefined) // => false\n * _.someIn(arr, _.isUndefined) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.some|some}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var someIn = _makeArrayChecker(false);\n\n /**\n * A curried version of {@link module:lamb.someIn|someIn} that uses the given predicate to\n * build a function waiting for the array-like to act upon.\n * @example\n * var data = [1, 3, 5, 6, 7, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var containsEvens = _.some(isEven);\n * var containsStrings = _.some(_.isType(\"String\"));\n *\n * containsEvens(data) // => true\n * containsStrings(data) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.someIn|someIn}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var some = _curry2(someIn, true);\n\n lamb.contains = contains;\n lamb.every = every;\n lamb.everyIn = everyIn;\n lamb.filter = filter;\n lamb.filterWith = filterWith;\n lamb.find = find;\n lamb.findIndex = findIndex;\n lamb.findIndexWhere = findIndexWhere;\n lamb.findWhere = findWhere;\n lamb.forEach = forEach;\n lamb.isIn = isIn;\n lamb.list = list;\n lamb.map = map;\n lamb.mapWith = mapWith;\n lamb.reduce = reduce;\n lamb.reduceRight = reduceRight;\n lamb.reduceRightWith = reduceRightWith;\n lamb.reduceWith = reduceWith;\n lamb.reverse = reverse;\n lamb.slice = slice;\n lamb.sliceAt = sliceAt;\n lamb.some = some;\n lamb.someIn = someIn;\n\n /**\n * Accepts a series of functions and builds a function that applies the received\n * arguments to each one and returns the first non-undefined value.
\n * Meant to work in sinergy with {@link module:lamb.case|case} and\n * {@link module:lamb.invoker|invoker}, can be useful as a strategy pattern for functions,\n * to mimic conditional logic or pattern matching, and also to build polymorphic functions.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var filterString = _.compose(_.invoker(\"join\", \"\"), _.filter);\n * var filterAdapter = _.adapter(\n * _.invoker(\"filter\"),\n * _.case(_.isType(\"String\"), filterString)\n * );\n *\n * filterAdapter([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterAdapter(\"123456\", isEven) // => \"246\"\n * filterAdapter({}, isEven) // => undefined\n *\n * // obviously it's composable\n * var filterWithDefault = _.adapter(filterAdapter, _.always(\"Not implemented\"));\n *\n * filterWithDefault([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterWithDefault(\"123456\", isEven) // => \"246\"\n * filterWithDefault({}, isEven) // => \"Not implemented\"\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.case|case}\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.6.0\n * @param {...Function} fn\n * @returns {Function}\n */\n function adapter () {\n var functions = list.apply(null, arguments);\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = functions[i].apply(this, arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n }\n\n /**\n * Accepts a series of predicates and builds a new one that returns true if they are all satisfied\n * by the same arguments. The functions in the series will be applied one at a time until a\n * false value is produced, which is returned immediately.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositiveEven = _.allOf(isEven, _.isGT(0));\n *\n * isPositiveEven(-2) // => false\n * isPositiveEven(11) // => false\n * isPositiveEven(6) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.anyOf|anyOf}\n * @since 0.1.0\n * @param {...Function} predicate\n * @returns {Function}\n */\n function allOf () {\n var predicates = list.apply(null, arguments);\n\n return function () {\n for (var i = 0, len = predicates.length; i < len; i++) {\n if (!predicates[i].apply(this, arguments)) {\n return false;\n }\n }\n\n return true;\n };\n }\n\n /**\n * Accepts a series of predicates and builds a new one that returns true if at least one of them is\n * satisfied by the received arguments. The functions in the series will be applied one at a time\n * until a true value is produced, which is returned immediately.\n * @example\n * var users = [\n * {id: 1, name: \"John\", group: \"guest\"},\n * {id: 2, name: \"Jane\", group: \"root\"},\n * {id: 3, name: \"Mario\", group: \"admin\"}\n * ];\n * var isInGroup = _.partial(_.hasKeyValue, [\"group\"]);\n * var isSuperUser = _.anyOf(isInGroup(\"admin\"), isInGroup(\"root\"));\n *\n * isSuperUser(users[0]) // => false\n * isSuperUser(users[1]) // => true\n * isSuperUser(users[2]) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.allOf|allOf}\n * @since 0.1.0\n * @param {...Function} predicate\n * @returns {Function}\n */\n function anyOf () {\n var predicates = list.apply(null, arguments);\n\n return function () {\n for (var i = 0, len = predicates.length; i < len; i++) {\n if (predicates[i].apply(this, arguments)) {\n return true;\n }\n }\n\n return false;\n };\n }\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValue\" comparison.
\n * Note that this doesn't behave as the strict equality operator, but rather as a shim of ES6's\n * [Object.is]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is}.\n * Differences are that 0 and -0 aren't the same value and, finally,\n * NaN is equal to itself.
\n * See also {@link module:lamb.is|is} for a curried version building a predicate and\n * {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ} to perform a \"SameValueZero\"\n * comparison.\n * @example\n * var testObject = {};\n *\n * _.areSame({}, testObject) // => false\n * _.areSame(testObject, testObject) // => true\n * _.areSame(\"foo\", \"foo\") // => true\n * _.areSame(0, -0) // => false\n * _.areSame(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.is|is}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSame (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : areSVZ(a, b);\n }\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValueZero\" comparison.
\n * With this comparison NaN is equal to itself, but 0 and -0 are\n * considered the same value.
\n * See also {@link module:lamb.isSVZ|isSVZ} for a curried version building a predicate and\n * {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.areSVZ({}, testObject) // => false\n * _.areSVZ(testObject, testObject) // => true\n * _.areSVZ(\"foo\", \"foo\") // => true\n * _.areSVZ(0, -0) // => true\n * _.areSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.isSVZ|isSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSVZ (a, b) {\n return a !== a ? b !== b : a === b; // eslint-disable-line no-self-compare\n }\n\n /**\n * Builds a case for {@link module:lamb.adapter|adapter}.
\n * The function will apply the received arguments to fn if the predicate is satisfied\n * with the same arguments, otherwise will return undefined.
\n * See also {@link module:lamb.condition|condition} to build a condition with two branching functions.\n * @example\n * var halveIfNumber = _.case(_.isType(\"Number\"), _.divideBy(2));\n *\n * halveIfNumber(2) // => 1\n * halveIfNumber(\"2\") // => undefined\n *\n * @memberof module:lamb\n * @category Logic\n * @alias case\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.condition|condition}\n * @since 0.51.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function case_ (predicate, fn) {\n return function () {\n return predicate.apply(this, arguments) ? fn.apply(this, arguments) : void 0;\n };\n }\n\n /**\n * Builds a function that will apply the received arguments to trueFn,\n * if the predicate is satisfied with the same arguments, or to falseFn otherwise.
\n * Although you can use other conditions as trueFn or falseFn,\n * it's probably better to use {@link module:lamb.adapter|adapter} to build more complex behaviours.
\n * See also {@link module:lamb.unless|unless} and {@link module:lamb.when|when} as they are\n * shortcuts to common use cases.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveEvenAndDoubleOdd = _.condition(isEven, _.divideBy(2), _.multiplyBy(2));\n *\n * halveEvenAndDoubleOdd(5) // => 10\n * halveEvenAndDoubleOdd(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @since 0.2.0\n * @param {Function} predicate\n * @param {Function} trueFn\n * @param {Function} falseFn\n * @returns {Function}\n */\n function condition (predicate, trueFn, falseFn) {\n return function () {\n return (predicate.apply(this, arguments) ? trueFn : falseFn).apply(this, arguments);\n };\n }\n\n /**\n * Verifies that the first given value is greater than the second.
\n * Wraps the native > operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.gt(today, pastDate) // => true\n * _.gt(pastDate, today) // => false\n * _.gt(3, 4) // => false\n * _.gt(3, 3) // => false\n * _.gt(3, 2) // => true\n * _.gt(0, -0) // => false\n * _.gt(-0, 0) // => false\n * _.gt(\"a\", \"A\") // => true\n * _.gt(\"b\", \"a\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gt (a, b) {\n return a > b;\n }\n\n /**\n * Verifies that the first given value is greater than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * >= operator, so -0 === 0.\n * @example\n * _.gte(3, 4) // => false\n * _.gte(3, 3) // => true\n * _.gte(3, 2) // => true\n * _.gte(0, -0) // => true\n * _.gte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gt|gt}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gte (a, b) {\n return a >= b;\n }\n\n /**\n * A curried version of {@link module:lamb.areSame|areSame}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValue\"\n * comparison.
\n * See also {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ}\n * to perform a \"SameValueZero\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.is(john);\n * var isNegativeZero = _.is(-0);\n * var isReallyNaN = _.is(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isNegativeZero(0) // => false\n * isNegativeZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSame|areSame}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var is = _curry2(areSame);\n\n /**\n * A right curried version of {@link module:lamb.gt|gt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than the one received by the predicate.\n * @example\n * var isGreaterThan5 = _.isGT(5);\n *\n * isGreaterThan5(3) // => false\n * isGreaterThan5(5) // => false\n * isGreaterThan5(7) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGT = _curry2(gt, true);\n\n /**\n * A right curried version of {@link module:lamb.gte|gte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than or equal to the one received by the predicate.\n * @example\n * var isPositiveOrZero = _.isGTE(0);\n *\n * isPositiveOrZero(-3) // => false\n * isPositiveOrZero(-0) // => true\n * isPositiveOrZero(0) // => true\n * isPositiveOrZero(5) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGT|isGT}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGTE = _curry2(gte, true);\n\n /**\n * A right curried version of {@link module:lamb.lt|lt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than the one received by the predicate.\n * @example\n * var isLessThan5 = _.isLT(5);\n *\n * isLessThan5(7) // => false\n * isLessThan5(5) // => false\n * isLessThan5(3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLT = _curry2(lt, true);\n\n /**\n * A right curried version of {@link module:lamb.lte|lte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than or equal to the one received by the predicate.\n * @example\n * var isNegativeOrZero = _.isLTE(0);\n *\n * isNegativeOrZero(5) // => false\n * isNegativeOrZero(-0) // => true\n * isNegativeOrZero(0) // => true\n * isNegativeOrZero(-3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLT|isLT}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLTE = _curry2(lte, true);\n\n /**\n * A curried version of {@link module:lamb.areSVZ|areSVZ}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValueZero\"\n * comparison.
\n * See also {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is}\n * to perform a \"SameValue\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.isSVZ(john);\n * var isZero = _.isSVZ(0);\n * var isReallyNaN = _.isSVZ(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isZero(0) // => true\n * isZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSVZ|areSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var isSVZ = _curry2(areSVZ);\n\n /**\n * Verifies that the first given value is less than the second.
\n * Wraps the native < operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.lt(today, pastDate) // => false\n * _.lt(pastDate, today) // => true\n * _.lt(3, 4) // => true\n * _.lt(3, 3) // => false\n * _.lt(3, 2) // => false\n * _.lt(0, -0) // => false\n * _.lt(-0, 0) // => false\n * _.lt(\"a\", \"A\") // => false\n * _.lt(\"a\", \"b\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lt (a, b) {\n return a < b;\n }\n\n /**\n * Verifies that the first given value is less than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * <= operator, so -0 === 0.\n * @example\n * _.lte(3, 4) // => true\n * _.lte(3, 3) // => true\n * _.lte(3, 2) // => false\n * _.lte(0, -0) // => true\n * _.lte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lt|lt}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lte (a, b) {\n return a <= b;\n }\n\n /**\n * Returns a predicate that negates the given one.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isOdd = _.not(isEven);\n *\n * isOdd(5) // => true\n * isOdd(4) // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @since 0.1.0\n * @param {Function} predicate\n * @returns {Function}\n */\n function not (predicate) {\n return function () {\n return !predicate.apply(this, arguments);\n };\n }\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate isn't satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.when|when} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its trueFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveUnlessIsEven = _.unless(isEven, _.divideBy(2));\n *\n * halveUnlessIsEven(5) // => 2.5\n * halveUnlessIsEven(6) // => 6\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.when|when}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function unless (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? value : fn.call(this, value);\n };\n }\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate is satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.unless|unless} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its falseFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var halveIfEven = _.when(isEven, _.divideBy(2));\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function when (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? fn.call(this, value) : value;\n };\n }\n\n lamb.adapter = adapter;\n lamb.allOf = allOf;\n lamb.anyOf = anyOf;\n lamb.areSame = areSame;\n lamb.areSVZ = areSVZ;\n lamb.case = case_;\n lamb.condition = condition;\n lamb.gt = gt;\n lamb.gte = gte;\n lamb.is = is;\n lamb.isGT = isGT;\n lamb.isGTE = isGTE;\n lamb.isLT = isLT;\n lamb.isLTE = isLTE;\n lamb.isSVZ = isSVZ;\n lamb.lt = lt;\n lamb.lte = lte;\n lamb.not = not;\n lamb.unless = unless;\n lamb.when = when;\n\n /**\n * A curried version of {@link module:lamb.sum|sum}.\n * @example\n * var add5 = _.add(5);\n *\n * _.add5(4) // => 9\n * _.add5(-2) // => 3\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.sum|sum}\n * @since 0.1.0\n * @param {Number} a\n * @returns {Function}\n */\n var add = _curry2(sum, true);\n\n /**\n * \"Clamps\" a number within the given limits, both included.
\n * The function will convert to number all its parameters before starting any\n * evaluation, and will return NaN if min is greater\n * than max.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n * _.clamp(0, 0, 10) // => 0\n * _.clamp(10, 0, 10) // => 10\n * _.is(_.clamp(-0, 0, 10), -0) // => true\n * _.clamp(10, 20, 15) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.clampWithin|clampWithin}\n * @since 0.13.0\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function clamp (n, min, max) {\n n = +n;\n min = +min;\n max = +max;\n\n if (min > max) {\n return NaN;\n } else {\n return n < min ? min : n > max ? max : n;\n }\n }\n\n /**\n * A curried version of {@link module:lamb.clamp|clamp}, expecting a min\n * and a max value, that builds a function waiting for the number to clamp.\n * @example\n * _.clampWithin(0, 10)(-5) // => 0\n * _.clampWithin(0, 10)(5) // => 5\n * _.clampWithin(0, 10)(15) // => 10\n * _.clampWithin(0, 10)(0) // => 0\n * _.clampWithin(0, 10)(10) // => 10\n * _.is(_.clampWithin(0, 10)(-0), -0) // => true\n * _.clampWithin(20, 15)(10) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.clamp|clamp}\n * @since 0.47.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Function}\n */\n var clampWithin = _makePartial3(clamp);\n\n /**\n * A curried version of {@link module:lamb.subtract|subtract} that expects the\n * subtrahend to build a function waiting for the minuend.\n * @example\n * var deduct5 = _.deduct(5);\n *\n * deduct5(12) // => 7\n * deduct5(3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.subtract|subtract}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var deduct = _curry2(subtract, true);\n\n /**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.divideBy|divideBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function divide (a, b) {\n return a / b;\n }\n\n /**\n * A curried version of {@link module:lamb.divide|divide} that expects a divisor to\n * build a function waiting for the dividend.\n * @example\n * var halve = divideBy(2);\n *\n * halve(10) // => 5\n * halve(5) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.divide|divide}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var divideBy = _curry2(divide, true);\n\n /**\n * Generates a sequence of values of the desired length with the provided iteratee.\n * The values being iterated, and received by the iteratee, are the results generated so far.\n * @example\n * var fibonacci = function (n, idx, results) {\n * return n + (results[idx - 1] || 0);\n * };\n *\n * _.generate(1, 10, fibonacci) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.range|range}\n * @since 0.21.0\n * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function generate (start, len, iteratee) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee(result[i], i, result));\n }\n\n return result;\n }\n\n /**\n * Verifies whether the received value is a finite number.
\n * Behaves almost as a shim of ES6's [Number.isFinite]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isFinite(5) // => true\n * _.isFinite(new Number(5)) // => true\n * _.isFinite(Infinity) // => false\n * _.isFinite(-Infinity) // => false\n * _.isFinite(\"5\") // => false\n * _.isFinite(NaN) // => false\n * _.isFinite(null) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @alias isFinite\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isFinite_ (value) {\n return type(value) === \"Number\" && isFinite(value);\n }\n\n /**\n * Verifies whether the received value is a number and an integer.\n * Behaves almost as a shim of ES6's [Number.isInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isInteger(5) // => true\n * _.isInteger(new Number(5)) // => true\n * _.isInteger(2.5) // => false\n * _.isInteger(Infinity) // => false\n * _.isInteger(-Infinity) // => false\n * _.isInteger(\"5\") // => false\n * _.isInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isSafeInteger|isSafeInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isInteger (value) {\n return type(value) === \"Number\" && value % 1 === 0;\n }\n\n /**\n * Verifies whether the received value is a \"safe integer\", meaning that is a number and that\n * can be exactly represented as an IEEE-754 double precision number.\n * The safe integers consist of all integers from -(253 - 1) inclusive to\n * 253 - 1 inclusive.
\n * Behaves almost as a shim of ES6's [Number.isSafeInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isSafeInteger(5) // => true\n * _.isSafeInteger(new Number(5)) // => true\n * _.isSafeInteger(Math.pow(2, 53) - 1) // => true\n * _.isSafeInteger(Math.pow(2, 53)) // => false\n * _.isSafeInteger(2e32) // => false\n * _.isSafeInteger(2.5) // => false\n * _.isSafeInteger(Infinity) // => false\n * _.isSafeInteger(-Infinity) // => false\n * _.isSafeInteger(\"5\") // => false\n * _.isSafeInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isInteger|isInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isSafeInteger (value) {\n return isInteger(value) && Math.abs(value) <= 9007199254740991;\n }\n\n /**\n * Performs the modulo operation and should not be confused with the\n * {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not\n * a truncated one, hence the sign of the dividend is not kept, unlike the\n * {@link module:lamb.remainder|remainder}.\n * @example\n * _.modulo(5, 3) // => 2\n * _.remainder(5, 3) // => 2\n *\n * _.modulo(-5, 3) // => 1\n * _.remainder(-5, 3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.remainder|remainder}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function modulo (a, b) {\n return a - (b * Math.floor(a / b));\n }\n\n /**\n * Multiplies two numbers.\n * @example\n * _.multiply(5, 3) // => 15\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.multiplyBy|multiplyBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function multiply (a, b) {\n return a * b;\n }\n\n /**\n * A curried version of {@link module:lamb.multiply|multiply}.\n * @example\n * var double = _.multiplyBy(2);\n *\n * double(5) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.multiply|multiply}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var multiplyBy = _curry2(multiply, true);\n\n /**\n * Generates a random integer between two given integers, both included.\n * Note that no safety measure is taken if the provided arguments aren't integers, so\n * you may end up with unexpected (not really) results.\n * For example randomInt(0.1, 1.2) could be 2.\n * @example\n *\n * _.randomInt(1, 10) // => an integer >=1 && <= 10\n *\n * @memberof module:lamb\n * @category Math\n * @since 0.1.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function randomInt (min, max) {\n return Math.floor(Math.random() * (max - min + 1) + min);\n }\n\n /**\n * Generates an arithmetic progression of numbers starting from start up to,\n * but not including, limit, using the given step.\n * @example\n * _.range(2, 10) // => [2, 3, 4, 5, 6, 7, 8, 9]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(0, 3, 1) // => [0, 1, 2]\n * _.range(-0, 3, 1) // => [-0, 1, 2]\n * _.range(1, -10, 2) // => []\n * _.range(3, 5, -1) // => []\n *\n * @example Behaviour if step happens to be zero:\n * _.range(2, 10, 0) // => [2]\n * _.range(2, -10, 0) // => [2]\n * _.range(2, 2, 0) // => []\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.generate|generate}\n * @since 0.1.0\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\n function range (start, limit, step) {\n start = _forceToNumber(start);\n limit = _forceToNumber(limit);\n step = arguments.length === 3 ? _forceToNumber(step) : 1;\n\n if (step === 0) {\n return limit === start ? [] : [start];\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n var result = Array(len);\n\n for (var i = 0, last = start; i < len; i++) {\n result[i] = last;\n last += step;\n }\n\n return result;\n }\n\n /**\n * Gets the remainder of the division of two numbers.\n * Not to be confused with the {@link module:lamb.modulo|modulo} as the remainder\n * keeps the sign of the dividend and may lead to some unexpected results.\n * @example\n * // example of wrong usage of the remainder\n * // (in this case the modulo operation should be used)\n * var isOdd = function (n) { return _.remainder(n, 2) === 1; };\n * isOdd(-3) // => false as -3 % 2 === -1\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.modulo|modulo}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function remainder (a, b) {\n return a % b;\n }\n\n /**\n * Subtracts two numbers.\n * @example\n * _.subtract(5, 3) // => 2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.deduct|deduct}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function subtract (a, b) {\n return a - b;\n }\n\n /**\n * Sums two numbers.\n * @example\n * _.sum(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.add|add}\n * @since 0.50.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function sum (a, b) {\n return a + b;\n }\n\n lamb.add = add;\n lamb.clamp = clamp;\n lamb.clampWithin = clampWithin;\n lamb.deduct = deduct;\n lamb.divide = divide;\n lamb.divideBy = divideBy;\n lamb.generate = generate;\n lamb.isFinite = isFinite_;\n lamb.isInteger = isInteger;\n lamb.isSafeInteger = isSafeInteger;\n lamb.modulo = modulo;\n lamb.multiply = multiply;\n lamb.multiplyBy = multiplyBy;\n lamb.randomInt = randomInt;\n lamb.range = range;\n lamb.remainder = remainder;\n lamb.subtract = subtract;\n lamb.sum = sum;\n\n /**\n * Accepts a constructor and builds a predicate expecting an object,\n * which will be tested to verify whether the prototype of the constructor\n * is in its prototype chain.
\n * Wraps in a convenient way the native\n * [instanceof]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof} operator.\n * @example\n * function SomeObjA () {}\n *\n * var a = new SomeObjA();\n * var sObj = new String(\"foo\");\n * var s = \"foo\";\n *\n * _.isInstanceOf(Object)(a) // => true\n * _.isInstanceOf(SomeObjA)(a) // => true\n *\n * _.isInstanceOf(Object)(sObj) // => true\n * _.isInstanceOf(String)(sObj) // => true\n *\n * _.isInstanceOf(Object)(s) // => false\n * _.isInstanceOf(String)(s) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.47.0\n * @param {*} constructor\n * @returns {Function}\n */\n function isInstanceOf (constructor) {\n return function (obj) {\n return obj instanceof constructor;\n };\n }\n\n /**\n * Verifies if a value is null or undefined.\n * @example\n * _.isNil(NaN) // => false\n * _.isNil({}) // => false\n * _.isNil(null) // => true\n * _.isNil(void 0) // => true\n * _.isNil() // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNull|isNull}\n * @see {@link module:lamb.isUndefined|isUndefined}\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNil (value) {\n return isNull(value) || isUndefined(value);\n }\n\n /**\n * Verifies if a value is null.\n * @example\n * _.isNull(null) // => true\n * _.isNull(void 0) // => false\n * _.isNull(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for undefined too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNull (value) {\n return value === null;\n }\n\n /**\n * Builds a predicate that expects a value to check against the specified type.\n * @example\n * var isString = _.isType(\"String\");\n *\n * isString(\"Hello\") // => true\n * isString(new String(\"Hi\")) // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.type|type}\n * @since 0.1.0\n * @param {String} typeName\n * @returns {Function}\n */\n function isType (typeName) {\n return function (value) {\n return type(value) === typeName;\n };\n }\n\n /**\n * Verifies if a value is undefined.\n * @example\n * _.isUndefined(null) // => false\n * _.isUndefined(void 0) // => true\n * _.isUndefined(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for null too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isUndefined (value) {\n return value === void 0;\n }\n\n /**\n * Retrieves the \"type tag\" from the given value.\n * @example\n * var x = 5;\n * var y = new Number(5);\n *\n * typeof x // => \"number\"\n * typeof y // => \"object\"\n * _.type(x) // => \"Number\"\n * _.type(y) // => \"Number\"\n *\n * _.type(Object.prototype.toString) // => \"Function\"\n * _.type(/a/) // => \"RegExp\"\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.9.0\n * @param {*} value\n * @returns {String}\n */\n function type (value) {\n return _objectProto.toString.call(value).slice(8, -1);\n }\n\n lamb.isInstanceOf = isInstanceOf;\n lamb.isNil = isNil;\n lamb.isNull = isNull;\n lamb.isType = isType;\n lamb.isUndefined = isUndefined;\n lamb.type = type;\n\n /**\n * A curried version of {@link module:lamb.getIndex|getIndex} that uses the provided index\n * to build a function expecting the array-like object holding the element we want to retrieve.\n * @example\n * var getFifthElement = _.getAt(4);\n *\n * getFifthElement([1, 2, 3, 4, 5]) // => 5\n * getFifthElement(\"foo bar\") // => \"b\"\n * getFifthElement([]) // => undefined\n * getFifthElement(\"foo\") // => undefined\n *\n * @example Using negative indexes:\n * _.getAt(-2)([1, 2, 3]) // => 2\n * _.getAt(-3)(\"foo\") // => \"f\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.16.0\n * @see {@link module:lamb.getIndex|getIndex}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @param {Number} index\n * @returns {Function}\n */\n var getAt = _curry2(getIndex, true);\n\n /**\n * Returns the value of the object property with the given key.\n * @example\n * var user = {name: \"John\"};\n *\n * _.getIn(user, \"name\") // => \"John\";\n * _.getIn(user, \"surname\") // => undefined\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getKey|getKey}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.18.0\n * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\n function getIn (obj, key) {\n return obj[key];\n }\n\n /**\n * Retrieves the element at the given index in an array-like object.
\n * Like {@link module:lamb.slice|slice} the index can be negative.
\n * If the index isn't supplied, or if its value isn't an integer within the array-like bounds,\n * the function will return undefined.
\n * getIndex will throw an exception when receives null or\n * undefined in place of an array-like object, but returns undefined\n * for any other value.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.getIndex(arr, 1) // => 2\n * _.getIndex(arr, -1) // => 5\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.getAt|getAt}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @since 0.23.0\n * @returns {*}\n */\n function getIndex (arrayLike, index) {\n var idx = _toNaturalIndex(index, _toArrayLength(arrayLike.length));\n\n return idx === idx ? arrayLike[idx] : void 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * A curried version of {@link module:lamb.getIn|getIn}.
\n * Receives a property name and builds a function expecting the object from which we want to retrieve\n * the property.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {name: \"jane\"};\n * var getName = _.getKey(\"name\");\n *\n * getName(user1) // => \"john\"\n * getName(user2) // => \"jane\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var getKey = _curry2(getIn, true);\n\n /**\n * Builds a partial application of {@link module:lamb.getPathIn|getPathIn} with the given\n * path and separator, expecting the object to act upon.
\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * var getPwd = _.getPath(\"login.password\");\n * var getUsername = _.getPath(\"login/user.name\", \"/\");\n *\n * getPwd(user) // => \"abc123\";\n * getUsername(user) // => \"jdoe\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var getPath = _makePartial3(getPathIn);\n\n /**\n * Gets a nested property value from an object using the given path.
\n * The path is a string with property names separated by dots by default, but\n * it can be customised with the optional third parameter.
\n * You can use integers in the path, even negative ones, to refer to array-like\n * object indexes, but the priority will be given to existing object keys:\n * the last example explains this particular case.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * },\n * scores: [\n * {id: 1, value: 10},\n * {id: 2, value: 20},\n * {id: 3, value: 30}\n * ]\n * };\n *\n * _.getPathIn(user, \"name\") // => \"John\"\n * _.getPathIn(user, \"login.password\") // => \"abc123\";\n * _.getPathIn(user, \"login/user.name\", \"/\") // => \"jdoe\"\n * _.getPathIn(user, \"name.foo\") // => undefined\n * _.getPathIn(user, \"name.foo.bar\") // => undefined\n *\n * @example Accessing array-like objects indexes:\n * _.getPathIn(user, \"login.password.1\") // => \"b\"\n * _.getPathIn(user, \"scores.0\") // => {id: 1, value: 10}\n * _.getPathIn(user, \"scores.-1.value\") // => 30\n *\n * @example Priority will be given to existing object keys over indexes:\n * _.getPathIn(user, \"scores.-1\") // => {id: 3, value: 30}\n *\n * // let's do something funny\n * user.scores[\"-1\"] = \"foo bar\";\n *\n * _.getPathIn(user, \"scores.-1\") // => \"foo bar\";\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getPath|getPath}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\n function getPathIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).target;\n }\n\n /**\n * Retrieves the first element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.head([1, 2, 3]) // => 1\n * _.head(\"hello\") // => \"h\"\n * _.head([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.last|last}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var head = getAt(0);\n\n /**\n * Retrieves the last element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.last([1, 2, 3]) // => 3\n * _.last(\"hello\") // => \"o\"\n * _.last([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.head|head}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var last = getAt(-1);\n\n /**\n * Builds a function that creates a copy of an array-like object with the given\n * index changed to the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.setAt(2, 99)(arr) // => [1, 2, 99, 4, 5]\n * arr // => [1, 2, 3, 4, 5]\n *\n * _.setAt(10, 99)(arr) // => [1, 2, 3, 4, 5] (not a reference to `arr`)\n *\n * @example Using negative indexes:\n * _.setAt(-1, 99)(arr) // => [1, 2, 3, 4, 99]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setIndex|setIndex}\n * @since 0.17.0\n * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\n var setAt = _makePartial3(_setIndex);\n\n /**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the remaining enumerable keys of the source object will be simply copied in the\n * result object without breaking references.
\n * If the specified key is not part of the source object, it will be added to the\n * result.
\n * The main purpose of the function is to work on simple plain objects used as\n * data structures, such as JSON objects, and makes no effort to play nice with\n * objects created from an OOP perspective (it's not worth it).
\n * For example the prototype of the result will be Object's regardless\n * of the source's one.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n *\n * _.setIn(user, \"name\", \"Jane\") // => {name: \"Jane\", surname: \"Doe\", age: 30}\n * _.setIn(user, \"gender\", \"male\") // => {name: \"John\", surname: \"Doe\", age: 30, gender: \"male\"}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setKey|setKey}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function setIn (source, key, value) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setIn(source, key, value);\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed to\n * the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.setIndex(arr, 1, 99) // => [1, 99, 3]\n * _.setIndex(arr, -1, 99) // => [1, 2, 99]\n * _.setIndex(arr, 10, 99) // => [1, 2, 3] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setAt|setAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} value\n * @returns {Array}\n */\n var setIndex = aritize(_setIndex, 3);\n\n /**\n * Builds a partial application of {@link module:lamb.setIn|setIn} with the provided\n * key and value.
\n * The resulting function expects the object to act upon.
\n * Please refer to {@link module:lamb.setIn|setIn}'s description for explanations about\n * how the copy of the source object is made.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n * var setAgeTo40 = _.setKey(\"age\", 40);\n *\n * setAgeTo40(user) // => {name: \"john\", surname: \"doe\", age: 40}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n var setKey = _makePartial3(setIn);\n\n /**\n * Builds a partial application of {@link module:lamb.setPathIn|setPathIn} expecting the\n * object to act upon.
\n * See {@link module:lamb.setPathIn|setPathIn} for more details and examples.\n * @example\n * var user = {id: 1, status: {active: false}};\n * var activate = _.setPath(\"status.active\", true);\n *\n * activate(user) // => {id: 1, status: {active: true}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPathIn|setPathIn}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function setPath (path, value, separator) {\n return function (source) {\n return setPathIn(source, path, value, separator);\n };\n }\n\n /**\n * Allows to change a nested value in a copy of the provided object.
\n * The function will delegate the \"set action\" to {@link module:lamb.setIn|setIn} or\n * {@link module:lamb.setAt|setAt} depending on the value encountered in the path,\n * so please refer to the documentation of those functions for specifics about the\n * implementation.
\n * Note anyway that the distinction will be between Arrays, delegated\n * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects),\n * which will be delegated to {@link module:lamb.setIn|setIn}.
\n * As a result of that, array-like objects will be converted to objects having numbers as keys\n * and paths targeting non-object values will be converted to empty objects.
\n * You can anyway target array elements using integers in the path, even negative ones, but\n * the priority will be given to existing, and enumerable, object keys.
\n * Non-enumerable properties encountered in the path will be considered as non-existent properties.
\n * Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can\n * use custom path separators.\n * @example\n * var user = {id: 1, status: {active : false, scores: [2, 4, 6]}};\n *\n * _.setPathIn(user, \"status.active\", true) // => {id: 1, status: {active : true, scores: [2, 4, 6]}}\n *\n * @example Targeting arrays:\n * _.setPathIn(user, \"status.scores.0\", 8) // => {id: 1, status: {active : false, scores: [8, 4, 6]}}\n *\n * // you can use negative indexes as well\n * _.setPathIn(user, \"status.scores.-1\", 8) // => {id: 1, status: {active : false, scores: [2, 4, 8]}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.setPathIn(user, \"scores.0.value\", 8);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 8, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPath|setPath}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function setPathIn (source, path, value, separator) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setPathIn(source, _toPathParts(path, separator), value);\n }\n\n /**\n * Builds a function that creates a copy of an array-like object with the given index\n * changed by applying the provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateAt(1, toUpperCase)(arr) // => [\"a\", \"B\", \"c\"]\n * _.updateAt(-1, toUpperCase)(arr) // => [\"a\", \"b\", \"C\"]\n * _.updateAt(10, toUpperCase)(arr) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.updateIndex|updateIndex}\n * @since 0.22.0\n * @param {Number} index\n * @param {Function} updater\n * @returns {Function}\n */\n function updateAt (index, updater) {\n return function (arrayLike) {\n return _setIndex(arrayLike, index, null, updater);\n };\n }\n\n /**\n * Creates a copy of the given object having the desired key value updated by applying\n * the provided function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIn(user, \"name\", toUpperCase) // => {name: \"JOHN\", visits: 2}\n * _.updateIn(user, \"surname\", toUpperCase) // => {name: \"John\", visits: 2}\n *\n * @example Non-enumerable properties will be treated as non-existent:\n * var user = Object.create({name: \"John\"}, {visits: {value: 2}});\n *\n * _.updateIn(user, \"visits\", _.add(1)) // => {name: \"John\", visits: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateKey|updateKey}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {Object} source\n * @param {String} key\n * @param {Function} updater\n * @returns {Object}\n */\n function updateIn (source, key, updater) {\n return _isEnumerable(source, key) ?\n _setIn(source, key, updater(source[key])) :\n _merge(enumerables, source);\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed by applying the\n * provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIndex(arr, 1, toUpperCase) // => [\"a\", \"B\", \"c\"]\n * _.updateIndex(arr, -1, toUpperCase) // => [\"a\", \"b\", \"C\"]\n * _.updateIndex(arr, 10, toUpperCase) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.updateAt|updateAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {Function} updater\n * @returns {Array}\n */\n var updateIndex = partial(_setIndex, [_, _, null, _]);\n\n /**\n * Builds a partial application of {@link module:lamb.updateIn|updateIn} with the provided\n * key and updater, expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var incrementVisits = _.updateKey(\"visits\", _.add(1));\n *\n * incrementVisits(user) // => {name: \"John\", visits: 3}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.updateIn|updateIn}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {String} key\n * @param {Function} updater\n * @returns {Function}\n */\n var updateKey = _makePartial3(updateIn);\n\n /**\n * Builds a partial application of {@link module:lamb.updatePathIn|updatePathIn}\n * expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var incrementScores = _.updatePath(\"status.scores\", _.mapWith(_.add(1)))\n *\n * incrementScores(user) // => {id: 1, status: {scores: [3, 5, 7], visits: 0}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePathIn|updatePathIn}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function updatePath (path, updater, separator) {\n return function (source) {\n return updatePathIn(source, path, updater, separator);\n };\n }\n\n /**\n * Allows to change a nested value in a copy of the given object by applying the provided\n * function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var inc = _.add(1);\n *\n * _.updatePathIn(user, \"status.visits\", inc) // => {id: 1, status: {scores: [2, 4, 6]}, visits: 1}\n *\n * @example Targeting arrays:\n * _.updatePathIn(user, \"status.scores.0\", inc) // => {id: 1, status: {scores: [3, 4, 6], visits: 0}}\n *\n * // you can use negative indexes as well\n * _.updatePathIn(user, \"status.scores.-1\", inc) // => {id: 1, status: {scores: [2, 4, 7], visits: 0}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.updatePathIn(user, \"scores.0.value\", increment);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 3, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePath|updatePath}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function updatePathIn (source, path, updater, separator) {\n var parts = _toPathParts(path, separator);\n var pathInfo = _getPathInfo(source, parts, false);\n\n if (pathInfo.isValid) {\n return _setPathIn(source, parts, updater(pathInfo.target));\n } else {\n return Array.isArray(source) ? slice(source, 0, source.length) : _merge(enumerables, source);\n }\n }\n\n lamb.getAt = getAt;\n lamb.getIn = getIn;\n lamb.getIndex = getIndex;\n lamb.getKey = getKey;\n lamb.getPath = getPath;\n lamb.getPathIn = getPathIn;\n lamb.head = head;\n lamb.last = last;\n lamb.setAt = setAt;\n lamb.setIn = setIn;\n lamb.setIndex = setIndex;\n lamb.setKey = setKey;\n lamb.setPath = setPath;\n lamb.setPathIn = setPathIn;\n lamb.updateAt = updateAt;\n lamb.updateIn = updateIn;\n lamb.updateIndex = updateIndex;\n lamb.updateKey = updateKey;\n lamb.updatePath = updatePath;\n lamb.updatePathIn = updatePathIn;\n\n /**\n * A curried version of {@link module:lamb.appendTo|appendTo} that uses the value to append\n * to build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.append(5)(arr) // => [1, 2, 3, 4, 5]\n * _.append([5])(arr) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.appendTo|appendTo}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {*} value\n * @returns {Function}\n */\n var append = _curry2(appendTo, true);\n\n /**\n * Appends the given value at the end of a copy of the provided array-like object.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.appendTo(arr, 5) // => [1, 2, 3, 4, 5]\n * _.appendTo(arr, [5]) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.append|append}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Array}\n */\n function appendTo (arrayLike, value) {\n return slice(arrayLike, 0, arrayLike.length).concat([value]);\n }\n\n /**\n * Returns an array of unique items present only in the first of the two given\n * array-like objects. To determine uniqueness the function uses the\n * [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 1, 3, 4];\n * var a2 = [2, 4, 5, 6];\n * var a3 = [3, 4, 5, 2, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a2, a3) // => [6]\n * _.difference(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.6.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} other\n * @returns {Array}\n */\n function difference (arrayLike, other) {\n var isNotInOther = partial(not(isIn), [other]);\n\n return uniques(filter(arrayLike, isNotInOther));\n }\n\n /**\n * A curried version of {@link module:lamb.dropFrom|dropFrom} that expects the number of elements\n * to drop to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.dropFrom|dropFrom} about passing a\n * negative n.\n * @example\n * var drop2 = _.drop(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.5.0\n * @see {@link module:lamb.dropFrom|dropFrom}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var drop = _curry2(dropFrom, true);\n\n /**\n * Builds an array without the first n elements of the given array or array-like object.\n * Note that, being this only a shortcut for a specific use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.dropFrom(arr, 2) // => [3, 4, 5]\n * _.dropFrom(arr, -1) // => [5]\n * _.dropFrom(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function dropFrom (arrayLike, n) {\n return slice(arrayLike, n, arrayLike.length);\n }\n\n /**\n * Builds a function that drops the first n elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropWhileIsEven = _.dropWhile(isEven);\n *\n * dropWhileIsEven([2, 4, 6, 8]) // => []\n * dropWhileIsEven([2, 4, 7, 8]) // => [7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.takeWhile|takeWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n function dropWhile (predicate) {\n return function (arrayLike) {\n return slice(arrayLike, _getNumConsecutiveHits(arrayLike, predicate), arrayLike.length);\n };\n }\n\n /**\n * Similar to {@link module:lamb.map|map}, but if the mapping function returns an array this will\n * be concatenated, rather than pushed, to the final result.\n * @example Showing the difference with map:\n * var words = [\"foo\", \"bar\"];\n * var toCharArray = function (s) { return s.split(\"\"); };\n *\n * _.map(words, toCharArray) // => [[\"f\", \"o\", \"o\"], [\"b\", \"a\", \"r\"]]\n * _.flatMap(words, toCharArray) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.flatMapWith|flatMapWith}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.1.0\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function flatMap (array, iteratee) {\n return reduce(array, function (result, el, idx, arr) {\n var v = iteratee(el, idx, arr);\n\n if (!Array.isArray(v)) {\n v = [v];\n }\n\n for (var i = 0, len = v.length, rLen = result.length; i < len; i++) {\n result[rLen + i] = v[i];\n }\n\n return result;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.flatMap|flatMap} that uses provided iteratee\n * to build a function expecting the array to act upon.\n * @example\n * var toCharArray = function (s) { return s.split(\"\"); };\n * var wordsToCharArray = _.flatMapWith(toCharArray);\n *\n * wordsToCharArray([\"foo\", \"bar\"]) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatMap|flatMap}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.11.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var flatMapWith = _curry2(flatMap, true);\n\n /**\n * Flattens an array.\n * @example Showing the difference with shallowFlatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.shallowFlatten|shallowFlatten}\n * @since 0.1.0\n * @param {Array} array\n * @returns {Array}\n */\n var flatten = _makeArrayFlattener(true);\n\n /**\n * Returns a copy of the given array-like object without the last element.\n * @example\n * _.init([1, 2, 3, 4]) // => [1, 2, 3]\n * _.init([1]) // => []\n * _.init([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.tail|tail}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var init = partial(slice, [_, 0, -1]);\n\n /**\n * Inserts the provided element in a copy of an array-like object at the\n * specified index.
\n * If the index is greater than the length of the array-like, the element\n * will be appended at the end.
\n * Negative indexes are allowed; when a negative index is out of bounds\n * the element will be inserted at the start of the resulting array.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insert(arr, 3, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, -2, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, 10, 99) // => [1, 2, 3, 4, 5, 99]\n * _.insert(arr, -10, 99) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.insertAt|insertAt}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} element\n * @returns {Array}\n */\n function insert (arrayLike, index, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n result.splice(index, 0, element);\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.insert|insert}\n * expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insertAt(3, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(-2, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(10, 99)(arr) // => [1, 2, 3, 4, 5, 99]\n * _.insertAt(-10, 99)(arr) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.insert|insert}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.27.0\n * @param {Number} index\n * @param {*} element\n * @returns {Function}\n */\n var insertAt = _makePartial3(insert);\n\n /**\n * Returns an array of every unique item that is included in all given arrays or array-like objects.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 2, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a2, a3) // => [5, 6]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.5.0\n * @param {...ArrayLike} arrayLike\n * @returns {Array}\n */\n function intersection () {\n if (arguments.length === 0) {\n return [];\n }\n\n var rest = _argsTail.apply(null, arguments);\n\n return filter(uniques(arguments[0]), function (item) {\n return everyIn(rest, contains(item));\n });\n }\n\n /**\n * Splits an array-like object in two lists: the first with the elements satisfying the given predicate,\n * the others with the remaining elements.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * _.partition(numbers, isEven) // => [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.partitionWith|partitionWith}\n * @since 0.11.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Array}\n */\n function partition (arrayLike, predicate) {\n var result = [[], []];\n var len = arrayLike.length;\n\n for (var i = 0, el; i < len; i++) {\n el = arrayLike[i];\n result[predicate(el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.partition|partition} that uses the provided\n * predicate to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * ];\n * var isActive = _.hasKeyValue(\"active\", true);\n * var splitByActiveStatus = _.partitionWith(isActive);\n *\n * splitByActiveStatus(users) // =>\n * // [[\n * // {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true}\n * // ], [\n * // {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * // {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * // ]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.partition|partition}\n * @since 0.11.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var partitionWith = _curry2(partition, true);\n\n /**\n * \"Plucks\" the values of the specified key from a list of objects.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n *\n * _.pluck(persons, \"age\") // => [12, 40, 18, 15]\n *\n * var lists = [\n * [1, 2],\n * [3, 4, 5],\n * [6]\n * ];\n *\n * _.pluck(lists, \"length\") // => [2, 3, 1]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pluckKey|pluckKey}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {String} key\n * @returns {Array}\n */\n function pluck (arrayLike, key) {\n return map(arrayLike, getKey(key));\n }\n\n /**\n * A curried version of {@link module:lamb.pluck|pluck} expecting the key to retrieve to\n * build a function waiting for the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n * var getAges = _.pluckKey(\"age\");\n *\n * getAges(persons) // => [12, 40, 18, 15]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pluck|pluck}\n * @since 0.12.0\n * @param {String} key\n * @returns {Function}\n */\n var pluckKey = compose(mapWith, getKey);\n\n /**\n * A curried version of {@link module:lamb.pullFrom|pullFrom} expecting\n * a list of values to build a function waiting for an array-like object.
\n * The new function will create an array copy of the array-like without\n * the specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var scores = [40, 20, 30, 10];\n * var newScores = [30, 10];\n * var pullNewScores = _.pull(newScores);\n *\n * pullNewScores(scores) // => [40, 20]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pullFrom|pullFrom}\n * @since 0.45.0\n * @param {ArrayLike} values\n * @returns {Function}\n */\n var pull = _curry2(pullFrom, true);\n\n /**\n * Creates an array copy of the given array-like object without the\n * specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.pullFrom(arr, [2, 5]) // => [1, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pull|pull}\n * @since 0.45.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} values\n * @returns {Array}\n */\n function pullFrom (arrayLike, values) {\n return values ? filter(arrayLike, function (element) {\n return !isIn(values, element);\n }) : slice(arrayLike, 0, arrayLike.length);\n }\n\n /**\n * Flattens the \"first level\" of an array.\n * @example Showing the difference with flatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatten|flatten}\n * @since 0.9.0\n * @param {Array} array\n * @returns {Array}\n */\n var shallowFlatten = _makeArrayFlattener(false);\n\n /**\n * Returns a copy of the given array-like object without the first element.\n * @example\n * _.tail([1, 2, 3, 4]) // => [2, 3, 4]\n * _.tail([1]) // => []\n * _.tail([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.init|init}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var tail = drop(1);\n\n /**\n * A curried version of {@link module:lamb.takeFrom|takeFrom} that expects the number of elements\n * to retrieve to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.takeFrom|takeFrom} about passing a\n * negative n.\n * @example\n * var take2 = _.take(2);\n *\n * take2([1, 2, 3, 4, 5]) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeFrom|takeFrom}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.5.0\n * @param {Number} n\n * @returns {Function}\n */\n var take = _curry2(takeFrom, true);\n\n /**\n * Retrieves the first n elements from an array or array-like object.
\n * Note that, being this a shortcut for a common use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.takeFrom(arr, 3) // => [1, 2, 3]\n * _.takeFrom(arr, -1) // => [1, 2, 3, 4]\n * _.takeFrom(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function takeFrom (arrayLike, n) {\n return slice(arrayLike, 0, n);\n }\n\n /**\n * Builds a function that takes the first n elements satisfying a predicate from\n * an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeWhileIsEven = _.takeWhile(isEven);\n *\n * takeWhileIsEven([1, 2, 4, 6, 8]) // => []\n * takeWhileIsEven([2, 4, 7, 8]) // => [2, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n function takeWhile (predicate) {\n return function (arrayLike) {\n return slice(arrayLike, 0, _getNumConsecutiveHits(arrayLike, predicate));\n };\n }\n\n /**\n * Transposes a matrix. Can also be used to reverse a {@link module:lamb.zip|zip} operation.
\n * Just like {@link module:lamb.zip|zip}, the received array-like objects will be truncated to the\n * shortest length.\n * @example Transposing a matrix:\n * _.transpose([\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ]) // =>\n * // [\n * // [1, 4, 7],\n * // [2, 5, 8],\n * // [3, 6, 9]\n * // ]\n *\n * @example Showing the relationship with zip:\n * var zipped = _.zip([\"a\", \"b\", \"c\"], [1, 2, 3]); // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.transpose(zipped) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function transpose (arrayLike) {\n var minLen = MAX_ARRAY_LENGTH;\n var len = _toArrayLength(arrayLike.length);\n\n if (len === 0) {\n return [];\n }\n\n for (var j = 0, elementLen; j < len; j++) {\n elementLen = _toArrayLength(arrayLike[j].length);\n\n if (elementLen < minLen) {\n minLen = elementLen;\n }\n }\n\n var result = Array(minLen);\n\n for (var i = 0, el; i < minLen; i++) {\n el = result[i] = Array(len);\n\n for (j = 0; j < len; j++) {\n el[j] = arrayLike[j][i];\n }\n }\n\n return result;\n }\n\n /**\n * Returns a list of every unique element present in the given array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.unionBy|unionBy} if you need to transform the values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.union([1, 2, 3, 2], [3, 4], [1, 5]) // => [1, 2, 3, 4, 5]\n * _.union(\"abc\", \"bcd\", \"cde\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.unionBy|unionBy}\n * @since 0.5.0\n * @param {...ArrayLike} arrayLike\n * @returns {Array}\n */\n var union = unionBy(identity);\n\n /**\n * Using the provided iteratee, builds a function that will return an array of the unique elements\n * in the provided array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.union|union} if you don't need to transform the values.\n * @example\n * var unionByFloor = _.unionBy(Math.floor);\n *\n * unionByFloor([2.8, 3.2, 1.5], [3.5, 1.2, 4]) // => [2.8, 3.2, 1.5, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.union|union}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function unionBy (iteratee) {\n return compose(uniquesBy(iteratee), flatMapWith(drop(0)), list);\n }\n\n /**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniquesBy|uniquesBy} if you need to transform your values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.uniques([-0, 1, 2, 0, 2, 3, 4, 3, 5, 1]) // => [-0, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.uniquesBy|uniquesBy}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var uniques = uniquesBy(identity);\n\n /**\n * Using the provided iteratee, builds a function that will return an array comprised of the\n * unique elements of an array-like object. The values being compared are the ones returned by\n * the iteratee.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniques|uniques} if you don't need to transform your values before the\n * comparison.\n * @example\n * var data = [\n * {id: \"1\", name: \"John\"},\n * {id: \"4\", name: \"Jane\"},\n * {id: \"5\", name: \"Joe\"},\n * {id: \"1\", name: \"Mario\"},\n * {id: \"5\", name: \"Paolo\"},\n * ];\n * var uniquesById = _.uniquesBy(_.getKey(\"id\"));\n *\n * uniquesById(data) // => [{id: \"1\", name: \"John\"}, {id: \"4\", name: \"Jane\"}, {id: \"5\", name: \"Joe\"}]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.uniques|uniques}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function uniquesBy (iteratee) {\n return function (arrayLike) {\n var result = [];\n var len = arrayLike.length;\n\n for (var i = 0, seen = [], hasNaN = false, value; i < len; i++) {\n value = iteratee(arrayLike[i], i, arrayLike);\n\n if (value === value) { // eslint-disable-line no-self-compare\n if (seen.indexOf(value) === -1) {\n seen[seen.length] = value;\n result[result.length] = arrayLike[i];\n }\n } else if (!hasNaN) {\n hasNaN = true;\n result[result.length] = arrayLike[i];\n }\n }\n\n return result;\n };\n }\n\n /**\n * Builds a list of arrays out of the given array-like objects by pairing items with the same index.
\n * The received array-like objects will be truncated to the shortest length.\n * @example\n * _.zip(\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3],\n * [true, false, true]\n * ) // => [[\"a\", 1, true], [\"b\", 2, false], [\"c\", 3, true]]\n *\n * _.zip([1, 2, 3, 4], [5, 6, 7]) // => [[1, 5], [2, 6], [3, 7]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.transpose|transpose} for the reverse operation\n * @see {@link module:lamb.zipWithIndex|zipWithIndex}\n * @since 0.14.0\n * @param {...ArrayLike} arrayLike\n * @returns {Array}\n */\n var zip = compose(transpose, list);\n\n /**\n * \"{@link module:lamb.zip|Zips}\" an array-like object by pairing its values with their index.\n * @example\n * _.zipWithIndex([\"a\", \"b\", \"c\"]) // => [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\n var zipWithIndex = mapWith(binary(list));\n\n lamb.append = append;\n lamb.appendTo = appendTo;\n lamb.difference = difference;\n lamb.drop = drop;\n lamb.dropFrom = dropFrom;\n lamb.dropWhile = dropWhile;\n lamb.flatMap = flatMap;\n lamb.flatMapWith = flatMapWith;\n lamb.flatten = flatten;\n lamb.init = init;\n lamb.insert = insert;\n lamb.insertAt = insertAt;\n lamb.intersection = intersection;\n lamb.partition = partition;\n lamb.partitionWith = partitionWith;\n lamb.pluck = pluck;\n lamb.pluckKey = pluckKey;\n lamb.pull = pull;\n lamb.pullFrom = pullFrom;\n lamb.shallowFlatten = shallowFlatten;\n lamb.tail = tail;\n lamb.take = take;\n lamb.takeFrom = takeFrom;\n lamb.takeWhile = takeWhile;\n lamb.transpose = transpose;\n lamb.union = union;\n lamb.unionBy = unionBy;\n lamb.uniques = uniques;\n lamb.uniquesBy = uniquesBy;\n lamb.zip = zip;\n lamb.zipWithIndex = zipWithIndex;\n\n /**\n * Transforms an array-like object in a lookup table with the keys generated by the provided\n * iteratee, having as values the count of matches for the key.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 17},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n * var getAgeStatus = function (person) { return person.age >= 18 ? \"adult\" : \"minor\"; };\n *\n * _.count(persons, getAgeStatus) // => {\"adult\": 1, \"minor\": 3}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var count = _groupWith(function (a) {\n return a ? ++a : 1;\n });\n\n /**\n * A curried version of {@link module:lamb.count|count} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCityOrUnknown = _.adapter(_.getKey(\"city\"), _.always(\"Unknown\"));\n * var countByCity = _.countBy(getCityOrUnknown);\n *\n * countByCity(persons) // => {\"New York\": 2, \"Rome\": 1, \"Unknown\": 1}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.count|count}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var countBy = _curry2(count, true);\n\n /**\n * Transforms an array-like object into a lookup table using the provided iteratee as a grouping\n * criterion to generate keys and values.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCity = _.getKey(\"city\");\n * var personsByCity = _.group(persons, getCity);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"undefined\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @example Adding a custom value for missing keys:\n *\n * var getCityOrUnknown = _.adapter(getCity, _.always(\"Unknown\"));\n *\n * var personsByCity = _.group(persons, getCityOrUnknown);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"Unknown\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var group = _groupWith(function (a, b) {\n if (!a) {\n return [b];\n }\n\n a[a.length] = b;\n\n return a;\n });\n\n /**\n * A curried version of {@link module:lamb.group|group} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 18},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n *\n * var getAgeStatus = function (person) { return person.age > 20 ? \"over 20\" : \"under 20\"; };\n * var groupByAgeStatus = _.groupBy(getAgeStatus);\n *\n * var personsByAgeStatus = groupByAgeStatus(persons);\n *\n * // \"personsByAgeStatus\" holds:\n * // {\n * // \"under 20\": [\n * // {\"name\": \"Jane\", \"age\": 12},\n * // {\"name\": \"Mario\", \"age\": 18},\n * // {\"name\": \"Paolo\", \"age\": 15}\n * // ],\n * // \"over 20\": [\n * // {\"name\": \"John\", \"age\": 40}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.group|group}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var groupBy = _curry2(group, true);\n\n /**\n * Similar to {@link module:lamb.group|group}, but the generated lookup table will have\n * only one element of the original array-like object for each value.
\n * Should be used only when you're sure that your iteratee won't produce\n * duplicate keys, otherwise only the last evaluated element will be in the result.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"id\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"},\n * // \"4\": {id: 4, name: \"John\"}\n * // }\n *\n * @example Result of an iteratee producing a duplicate key:\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"name\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"John\": {\"id\": 4, \"name\": \"John\"},\n * // \"Jane\": {\"id\": 2, \"name\": \"Jane\"},\n * // \"Mario\": {\"id\": 3, \"name\": \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.indexBy|indexBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var index = _groupWith(function (a, b) {\n return b;\n });\n\n /**\n * A curried version of {@link module:lamb.index|index} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"}\n * ];\n * var indexByID = _.indexBy(_.getKey(\"id\"));\n *\n * var indexedUsers = indexByID(users);\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.index|index}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var indexBy = _curry2(index, true);\n\n lamb.count = count;\n lamb.countBy = countBy;\n lamb.group = group;\n lamb.groupBy = groupBy;\n lamb.index = index;\n lamb.indexBy = indexBy;\n\n /**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted\n * copy of an array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you\n * can also pass simple \"reader\" functions and default ascending sorters will be built for you.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used\n * in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type,\n * they will be compared as strings.\n *\n * @example Stable sort:\n * var persons = [\n * {\"name\": \"John\", \"surname\" :\"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"},\n * {\"name\": \"John\", \"surname\" :\"Moe\"},\n * {\"name\": \"Jane\", \"surname\": \"Foe\"}\n * ];\n *\n * var personsByName = _.sort(persons, _.getKey(\"name\"));\n *\n * // personsByName holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Stable multi-sort:\n * var personsByNameAscSurnameDesc = _.sort(\n * persons,\n * _.getKey(\"name\"),\n * _.sorterDesc(_.getKey(\"surname\"))\n * );\n *\n * // personsByNameAscSurnameDesc holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Using custom comparers:\n * var localeSorter = new Intl.Collator(\"it\");\n * var chars = [\"a\", \"è\", \"à\", \"é\", \"c\", \"b\", \"e\"];\n *\n * _.sort(chars, localeSorter) // => [\"a\", \"à\", \"b\", \"c\", \"e\", \"é\", \"è\"]\n *\n * var localeSorterDesc = _.sorterDesc(_.identity, localeSorter.compare);\n *\n * _.sort(chars, localeSorterDesc) // => [\"è\", \"é\", \"e\", \"c\", \"b\", \"à\", \"a\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {ArrayLike} arrayLike\n * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}]\n * @returns {Array}\n */\n function sort (arrayLike) {\n var criteria = _makeCriteria(_argsTail.apply(null, arguments));\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = {value: arrayLike[i], index: i};\n }\n\n result.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result[i] = result[i].value;\n }\n\n return result;\n }\n\n /**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example With simple values:\n * _.sortedInsert([], 1) // => [1]\n * _.sortedInsert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.sortedInsert([4, 2, 1], 3, _.sorterDesc()) // => [4, 3, 2, 1]\n *\n * @example With complex values:\n * var persons = [\n * {\"name\": \"jane\", \"surname\": \"doe\"},\n * {\"name\": \"John\", \"surname\": \"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * ];\n *\n * var getLowerCaseName = _.compose(\n * _.invoker(\"toLowerCase\"),\n * _.getKey(\"name\")\n * );\n *\n * var result = _.sortedInsert(\n * persons,\n * {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * getLowerCaseName\n * );\n *\n * // `result` holds:\n * // [\n * // {\"name\": \"jane\", \"surname\": \"doe\"},\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt} to insert the element\n * at a specific index\n * @since 0.27.0\n * @param {ArrayLike} arrayLike\n * @param {*} element\n * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}] - The sorting criteria\n * used to sort the array.\n * @returns {Array}\n */\n function sortedInsert (arrayLike, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n if (arguments.length === 1) {\n return result;\n }\n\n var len = arguments.length - 2;\n var sorters = Array(len);\n\n for (var i = 0; i < len; i++) {\n sorters[i] = arguments[i + 2];\n }\n\n var criteria = _makeCriteria(sorters);\n var idx = _getInsertionIndex(result, element, _compareWith(criteria), 0, result.length);\n\n result.splice(idx, 0, element);\n\n return result;\n }\n\n /**\n * Creates an ascending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.1.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorter = partial(_sorter, [_, false, _]);\n\n /**\n * Creates a descending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @since 0.15.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorterDesc = partial(_sorter, [_, true, _]);\n\n /**\n * Builds a partial application of {@link module:lamb.sort|sort} using the provided criteria.\n * The returned function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function,\n * but you can also pass simple \"reader\" functions and default ascending sorters will be built.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used in\n * the comparison.
\n * See {@link module:lamb.sort|sort} for more examples.\n *\n * @example\n * var sortAsNumbers = _.sortWith(parseFloat);\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * sortAsNumbers(weights) // => [\"1 Kg\", \"2 Kg\", \"7 Kg\", \"10 Kg\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}]\n * @returns {Function}\n */\n function sortWith () {\n var sorters = list.apply(null, arguments);\n\n return function (arrayLike) {\n return sort.apply(null, [arrayLike].concat(sorters));\n };\n }\n\n lamb.sort = sort;\n lamb.sortedInsert = sortedInsert;\n lamb.sorter = sorter;\n lamb.sorterDesc = sorterDesc;\n lamb.sortWith = sortWith;\n\n /**\n * Applies the given function to a list of arguments.\n * @example\n * _.application(_.sum, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.apply|apply}, {@link module:lamb.applyTo|applyTo}\n * @since 0.47.0\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\n function application (fn, args) {\n return fn.apply(this, Object(args));\n }\n\n /**\n * A left-curried version of {@link module:lamb.application|application}. Expects the function\n * to apply and builds a function waiting for the arguments array.\n * @example\n * var arrayMax = _.apply(Math.max);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.applyTo|applyTo}\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n var apply = _curry2(application);\n\n /**\n * A right-curried version of {@link module:lamb.application|application}. Expects an array-like\n * object to use as arguments and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyToData = _.applyTo(data);\n *\n * applyToData(_.sum) // => 7\n * applyToData(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.apply|apply}\n * @since 0.47.0\n * @param {ArrayLike} args\n * @returns {Function}\n */\n var applyTo = _curry2(application, true);\n\n /**\n * Builds a new function that passes only the specified amount of arguments to the original one.
\n * As {@link module:lamb.slice|slice} is used to extract the arguments, you can also\n * pass a negative arity.\n * @example\n * Math.max(10, 11, 45, 99) // => 99\n * _.aritize(Math.max, 2)(10, 11, 45, 99) // => 11\n *\n * @example Using a negative arity:\n * _.aritize(Math.max, -1)(10, 11, 45, 99) // => 45\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.binary|binary}, {@link module:lamb.unary|unary} for common use cases shortcuts\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\n function aritize (fn, arity) {\n return function () {\n var n = _toInteger(arity);\n var args = list.apply(null, arguments).slice(0, n);\n\n for (var i = args.length; i < n; i++) {\n args[i] = void 0;\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Decorates the received function so that it can be called with\n * placeholders to build a partial application of it.
\n * The difference with {@link module:lamb.partial|partial} is that, as long as\n * you call the generated function with placeholders, another partial application\n * of the original function will be built.
\n * The final application will happen when one of the generated functions is\n * invoked without placeholders, using the parameters collected so far.
\n * This function comes in handy when you need to build different specialized\n * functions starting from a basic one, but it's also useful when dealing with\n * optional parameters as you can decide to apply the function even if its arity\n * hasn't been entirely consumed.\n * @example Explaining the function's behaviour:\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + c;\n * });\n *\n * f(4, 3, 2) // => 9\n * f(4, _, 2)(3) // => 9\n * f(_, 3, _)(4, _)(2) // => 9\n *\n * @example Exploiting optional parameters:\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + (c || 0);\n * });\n *\n * var addFive = f(5, _);\n * addFive(2) // => 7\n *\n * var addNine = addFive(4, _);\n * addNine(11) // => 20\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.@@lamb/placeholder|@@lamb/placeholder}\n * @since 0.36.0\n * @param {Function} fn\n * @returns {Function}\n */\n function asPartial (fn) {\n return _asPartial(fn, []);\n }\n\n /**\n * Builds a function that passes only two arguments to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * _.list(1, 2, 3, 4, 5) // => [1, 2, 3, 4, 5]\n * _.binary(_.list)(1, 2, 3, 4, 5) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.unary|unary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function binary (fn) {\n return function (a, b) {\n return fn.call(this, a, b);\n };\n }\n\n /**\n * Accepts a series of functions and builds a new function. The functions in the series\n * will then be applied, in order, with the values received by the function built with\n * collect.
\n * The collected results will be returned in an array.\n * @example\n * var user = {\n * id: \"jdoe\",\n * name: \"John\",\n * surname: \"Doe\",\n * scores: [2, 4, 7]\n * };\n * var getIDAndLastScore = _.collect(_.getKey(\"id\"), _.getPath(\"scores.-1\"));\n *\n * getIDAndLastScore(user) // => [\"jdoe\", 7]\n *\n * @example\n * var minAndMax = _.collect(Math.min, Math.max);\n *\n * minAndMax(3, 1, -2, 5, 4, -1) // => [-2, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.35.0\n * @param {...Function} fn\n * @returns {Function}\n */\n function collect () {\n var functions = list.apply(null, arguments);\n\n return function () {\n return map(functions, applyTo(arguments));\n };\n }\n\n /**\n * Transforms the evaluation of the given function in the evaluation of a sequence of functions\n * expecting only one argument. Each function of the sequence is a partial application of the\n * original one, which will be applied when the specified (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryRight|curryRight}\n * for right currying.\n * @example\n * var makeWithKeys = _.curry(_.make);\n * var makePerson = makeWithKeys([\"name\", \"surname\"]);\n *\n * makePerson([\"John\", \"Doe\"]) // => {name: \"John\", surname: \"Doe\"};\n * makePerson([\"Mario\", \"Rossi\"]) // => {name: \"Mario\", surname: \"Rossi\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curry (fn, arity) {\n return _curry(fn, arity, false);\n }\n\n /**\n * Builds an auto-curried function. The resulting function can be called multiple times with\n * any number of arguments, and the original function will be applied only when the specified\n * (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryableRight|curryableRight}\n * for right currying.\n * @example\n * var collectFourElements = _.curryable(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2)(3, 4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3, 4, 5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3)(4, 5) // => [2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.6.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryable (fn, arity) {\n return _curry(fn, arity, false, true);\n }\n\n /**\n * Same as {@link module:lamb.curryable|curryable}, but currying starts from the rightmost argument.\n * @example\n * var collectFourElements = _.curryableRight(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2)(3, 4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3, 4, 5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3)(4, 5) // => [5, 4, 3, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryable|curryable}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryableRight (fn, arity) {\n return _curry(fn, arity, true, true);\n }\n\n /**\n * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var makeWithValues = _.curryRight(_.make);\n * var makeJohnDoe = makeWithValues([\"John\", \"Doe\"]);\n *\n * makeJohnDoe([\"name\", \"surname\"]) // => {name: \"John\", surname: \"Doe\"};\n * makeJohnDoe([\"firstName\", \"lastName\"]) // => {firstName: \"John\", lastName: \"Doe\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curry|curry}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryRight (fn, arity) {\n return _curry(fn, arity, true);\n }\n\n /**\n * Returns a function that will execute the given function only if it stops being called for the\n * specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call\n * happens immediately.\n * @example A common use case of debounce in a browser environment:\n * var updateLayout = function () {\n * // some heavy DOM operations here\n * };\n *\n * window.addEventListener(\"resize\", _.debounce(updateLayout, 200), false);\n *\n * // The resize event is fired repeteadly until the user stops resizing the\n * // window, while the `updateLayout` function is called only once: 200 ms\n * // after he stopped.\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.throttle|throttle}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds\n * @returns {Function}\n */\n function debounce (fn, timespan) {\n var timeoutID;\n\n return function () {\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(this, args);\n }.bind(this);\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n }\n\n /**\n * Returns a function that applies the original function with the arguments in reverse order.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n * _.flip(_.list)(1, 2, 3) // => [3, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n function flip (fn) {\n return function () {\n var args = list.apply(null, arguments).reverse();\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Builds a function that returns the argument received at the given index.
\n * As with {@link module:lamb.getAt|getAt} negative indexes are allowed.
\n * The resulting function will return undefined if no arguments are\n * passed or if the index is out of bounds.\n * @example\n * var getFirstArg = getArgAt(0);\n * var getLastArg = getArgAt(-1);\n *\n * getFirstArg(1, 2, 3) // => 1\n * getLastArg(1, 2, 3) // => 3\n *\n * getArgAt()(1, 2, 3) // => undefined\n * getArgAt(6)(1, 2, 3) // => undefined\n * getArgAt(1)() // => undefined\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.17.0\n * @param {Number} idx\n * @returns {Function}\n */\n function getArgAt (idx) {\n return function () {\n return arguments[_toNaturalIndex(idx, arguments.length)];\n };\n }\n\n /**\n * Builds a function that will invoke the given method name on any received object and\n * return the result. If no method with such name is found the function will return\n * undefined.
\n * Along with the method name it's possible to supply some arguments that will be bound to the\n * method call. Further arguments can also be passed when the function is actually called, and\n * they will be concatenated to the bound ones.
\n * Returning undefined is a behaviour meant to quickly create a case for\n * {@link module:lamb.adapter|adapter} without the need to check for the existence of the\n * desired method.
\n * See also {@link module:lamb.generic|generic} to create functions out of object methods.\n * @example Basic polymorphism with invoker:\n * var polySlice = _.invoker(\"slice\");\n *\n * polySlice([1, 2, 3, 4, 5], 1, 3) // => [2, 3]\n * polySlice(\"Hello world\", 1, 3) // => \"el\"\n *\n * @example With bound arguments:\n * var substrFrom2 = _.invoker(\"substr\", 2);\n * substrFrom2(\"Hello world\") // => \"llo world\"\n * substrFrom2(\"Hello world\", 5) // => \"llo w\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invokerOn|invokerOn}\n * @since 0.1.0\n * @param {String} methodName\n * @param {...*} [boundArg]\n * @returns {Function}\n */\n function invoker (methodName) {\n return partial(_invoker, [_argsTail.apply(null, arguments), methodName]);\n }\n\n /**\n * Accepts an object and builds a function expecting a method name, and optionally arguments,\n * to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the\n * function will return undefined.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var arr = [1, 2, 3, 4, 5];\n * var invokerOnArr = _.invokerOn(arr);\n *\n * invokerOnArr(\"filter\", isEven) // => [2, 4]\n * invokerOnArr(\"slice\", 1, 3) // => [2, 3]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.15.0\n * @param {Object} target\n * @returns {Function}\n */\n function invokerOn (target) {\n return partial(_invoker, [[], _, target]);\n }\n\n /**\n * Builds a function that allows to map over the received arguments before applying them\n * to the original one.\n * @example\n * var sumArray = _.reduceWith(_.sum);\n * var sumArgs = _.compose(sumArray, _.list);\n *\n * sumArgs(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, [_, 2]);\n * var sumSquares = _.mapArgs(sumArgs, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.tapArgs|tapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\n function mapArgs (fn, mapper) {\n return compose(apply(fn), mapWith(mapper), list);\n }\n\n /**\n * Creates a pipeline of functions, where each function consumes the result of the previous one.\n * @example\n * var square = _.partial(Math.pow, [_, 2]);\n * var getMaxAndSquare = _.pipe(Math.max, square);\n *\n * getMaxAndSquare(3, 5) // => 25\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.compose|compose}\n * @since 0.1.0\n * @param {...Function} fn\n * @returns {Function}\n */\n var pipe = flip(compose);\n\n /**\n * Builds a function that allows to \"tap\" into the arguments of the original one.\n * This allows to extract simple values from complex ones, transform arguments or simply intercept them.\n * If a \"tapper\" isn't found the argument is passed as it is.\n * @example\n * var someObject = {count: 5};\n * var someArrayData = [2, 3, 123, 5, 6, 7, 54, 65, 76, 0];\n * var getDataAmount = _.tapArgs(_.sum, [_.getKey(\"count\"), _.getKey(\"length\")]);\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.mapArgs|mapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {Function[]} tappers\n * @returns {Function}\n */\n function tapArgs (fn, tappers) {\n return function () {\n var len = arguments.length;\n var tappersLen = tappers.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(i < tappersLen ? tappers[i](arguments[i]) : arguments[i]);\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Returns a function that will invoke the passed function at most once in the given timespan.
\n * The first call in this case happens as soon as the function is invoked; see also\n * {@link module:lamb.debounce|debounce} for a different behaviour where the first call is delayed.\n * @example\n * var log = _.throttle(console.log.bind(console), 5000);\n *\n * log(\"Hi\"); // console logs \"Hi\"\n * log(\"Hi again\"); // nothing happens\n * // after five seconds\n * log(\"Hello world\"); // console logs \"Hello world\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.debounce|debounce}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds.\n * @returns {Function}\n */\n function throttle (fn, timespan) {\n var result;\n var lastCall = 0;\n\n return function () {\n var now = Date.now();\n\n if (now - lastCall >= timespan) {\n lastCall = now;\n result = fn.apply(this, arguments);\n }\n\n return result;\n };\n }\n\n /**\n * Builds a function that passes only one argument to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * _.map(weights, _.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.binary|binary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function unary (fn) {\n return function (a) {\n return fn.call(this, a);\n };\n }\n\n lamb.application = application;\n lamb.apply = apply;\n lamb.applyTo = applyTo;\n lamb.aritize = aritize;\n lamb.asPartial = asPartial;\n lamb.binary = binary;\n lamb.collect = collect;\n lamb.curry = curry;\n lamb.curryRight = curryRight;\n lamb.curryable = curryable;\n lamb.curryableRight = curryableRight;\n lamb.debounce = debounce;\n lamb.flip = flip;\n lamb.getArgAt = getArgAt;\n lamb.invoker = invoker;\n lamb.invokerOn = invokerOn;\n lamb.mapArgs = mapArgs;\n lamb.pipe = pipe;\n lamb.tapArgs = tapArgs;\n lamb.throttle = throttle;\n lamb.unary = unary;\n\n /**\n * Creates an array with all the enumerable properties of the given object.\n * @example Showing the difference with {@link module:lamb.keys|keys}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.keys|keys}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {String[]}\n */\n var enumerables = _unsafeKeyListFrom(_safeEnumerables);\n\n /**\n * Builds an object from a list of key / value pairs like the one\n * returned by {@link module:lamb.pairs|pairs} or {@link module:lamb.ownPairs|ownPairs}.
\n * In case of duplicate keys the last key / value pair is used.\n * @example\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"c\", 3]]) // => {\"a\": 1, \"b\": 2, \"c\": 3}\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"a\", 3]]) // => {\"a\": 3, \"b\": 2}\n * _.fromPairs([[1], [void 0, 2], [null, 3]]) // => {\"1\": undefined, \"undefined\": 2, \"null\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.ownPairs|ownPairs}, {@link module:lamb.pairs|pairs}\n * @since 0.8.0\n * @param {Array>} pairsList\n * @returns {Object}\n */\n function fromPairs (pairsList) {\n var result = {};\n\n forEach(pairsList, function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n }\n\n /**\n * Makes an object immutable by recursively calling [Object.freeze]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze}\n * on its members.
\n * Any attempt to extend or modify the object can throw a TypeError or fail silently,\n * depending on the environment and the [strict mode]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode} directive.\n * @example\n * var user = _.immutable({\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\"\n * },\n * luckyNumbers: [13, 17]\n * });\n *\n * // All of these statements will fail and possibly\n * // throw a TypeError (see the function description)\n * user.name = \"Joe\";\n * delete user.name;\n * user.newProperty = [];\n * user.login.password = \"foo\";\n * user.luckyNumbers.push(-13);\n *\n * @memberof module:lamb\n * @category Object\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Object}\n */\n function immutable (obj) {\n return _immutable(obj, []);\n }\n\n /**\n * Retrieves the list of the own enumerable properties of an object.
\n * Although [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * is already present in ECMAScript 5, its behaviour changed in the subsequent specifications\n * of the standard.
\n * This function shims the ECMAScript 6 version, by forcing a conversion to\n * object for any value but null and undefined.\n * @example Showing the difference with {@link module:lamb.enumerables|enumerables}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.enumerables(foo) // => [\"d\", \"a\"]\n * _.keys(foo) // => [\"d\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.enumerables|enumerables}\n * @since 0.25.1\n * @param {Object} obj\n * @returns {String[]}\n */\n var keys = _unsafeKeyListFrom(_safeKeys);\n\n /**\n * Builds an object from the two given lists, using the first one as keys and the last\n * one as values.
\n * If the list of keys is longer than the values one, the keys will be created with\n * undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.\n * @example\n * _.make([\"a\", \"b\", \"c\"], [1, 2, 3]) // => {a: 1, b: 2, c: 3}\n * _.make([\"a\", \"b\", \"c\"], [1, 2]) // => {a: 1, b: 2, c: undefined}\n * _.make([\"a\", \"b\"], [1, 2, 3]) // => {a: 1, b: 2}\n * _.make([null, void 0, 2], [1, 2, 3]) // => {\"null\": 1, \"undefined\": 2, \"2\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.tear|tear}, {@link module:lamb.tearOwn|tearOwn} for the reverse operation\n * @since 0.8.0\n * @param {String[]} names\n * @param {ArrayLike} values\n * @returns {Object}\n */\n function make (names, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = names.length; i < len; i++) {\n result[names[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n }\n\n /**\n * Creates a new object by applying the given function\n * to all enumerable properties of the source one.\n * @example\n * var weights = {\n * john: \"72.5 Kg\",\n * jane: \"52.3 Kg\"\n * };\n *\n * _.mapValues(weights, parseFloat) // => {john: 72.5, jane: 52.3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValuesWith|mapValuesWith}\n * @since 0.54.0\n * @param {Object} source\n * @param {ObjectIteratorCallback} fn\n * @returns {Object}\n */\n function mapValues (source, fn) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n result[key] = fn(source[key], key, source);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.mapValues|mapValues}.
\n * Expects a mapping function to build a new function waiting for the\n * object to act upon.\n * @example\n * var incValues = _.mapValuesWith(_.add(1));\n * var results = {\n * first: 10,\n * second: 5,\n * third: 3\n * };\n *\n * incValues(results) // => {first: 11, second: 6, third: 4}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValues|mapValues}\n * @since 0.54.0\n * @function\n * @param {Function} fn\n * @returns {Function}\n */\n var mapValuesWith = _curry2(mapValues, true);\n\n /**\n * Merges the enumerable properties of the provided sources into a new object.
\n * In case of key homonymy each source has precedence over the previous one.\n * @example\n * _.merge({a: 1}, {b: 3, c: 4}, {b: 5}) // => {a: 1, b: 5, c: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.merge([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.merge(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.merge({a: 2}, 99, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mergeOwn|mergeOwn} to merge own properties only\n * @since 0.10.0\n * @function\n * @param {...Object} source\n * @returns {Object}\n */\n var merge = partial(_merge, [enumerables]);\n\n /**\n * Same as {@link module:lamb.merge|merge}, but only the own properties of the\n * sources are taken into account.\n * @example Showing the difference with merge:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * var bar = {d: 4};\n *\n * _.merge(foo, bar) // => {a: 1, b: 2, c: 3, d: 4}\n * _.mergeOwn(foo, bar) // => {c: 3, d: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.mergeOwn([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.mergeOwn(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.mergeOwn({a: 2}, 99, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.merge|merge} to merge all enumerable properties\n * @since 0.12.0\n * @function\n * @param {...Object} source\n * @returns {Object}\n */\n var mergeOwn = partial(_merge, [keys]);\n\n /**\n * Same as {@link module:lamb.pairs|pairs}, but only the own enumerable properties of the object are\n * taken into account.
\n * See also {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example Showing the difference with pairs:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.pairs(foo) // => [[\"c\", 3], [\"b\", 2], [\"a\", 1]]\n * _.ownPairs(foo) // => [[\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pairs|pairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var ownPairs = _pairsFrom(keys);\n\n /**\n * Same as {@link module:lamb.values|values}, but only the own enumerable properties of the object are\n * taken into account.
\n * @example Showing the difference with values:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.values(foo) // => [3, 2, 1]\n * _.ownValues(foo) // => [3]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.values|values}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var ownValues = _valuesFrom(keys);\n\n /**\n * Converts an object into an array of key / value pairs of its enumerable properties.
\n * See also {@link module:lamb.ownPairs|ownPairs} for picking only the own enumerable\n * properties and {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example\n * _.pairs({a: 1, b: 2, c: 3}) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownPairs|ownPairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var pairs = _pairsFrom(enumerables);\n\n /**\n * Returns an object containing only the specified properties of the given object.
\n * Non existent properties will be ignored.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.pick(user, [\"name\", \"age\"]) // => {\"name\": \"john\", \"age\": 30};\n * _.pick(user, [\"name\", \"email\"]) // => {\"name\": \"john\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pickIf|pickIf}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\n function pick (source, whitelist) {\n var result = {};\n\n for (var i = 0, len = whitelist.length, key; i < len; i++) {\n key = whitelist[i];\n\n if (has(source, key)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be included in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var pickIfIsString = _.pickIf(_.isType(\"String\"));\n *\n * pickIfIsString(user) // => {name: \"john\", surname: \"doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n function pickIf (predicate) {\n return function (source) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n if (predicate(source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n }\n\n /**\n * A curried version of {@link module:lamb.pick|pick}, expecting a whitelist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.pickKeys([\"id\", \"active\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var select = _.compose(_.mapWith, _.pickKeys);\n * var selectUserInfo = select([\"id\", \"active\"]);\n *\n * selectUserInfo(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickIf|pickIf}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.35.0\n * @param {String[]} whitelist\n * @returns {Function}\n */\n var pickKeys = _curry2(pick, true);\n\n /**\n * Creates a copy of the given object with its enumerable keys renamed as\n * indicated in the provided lookup table.\n * @example\n * var person = {\"firstName\": \"John\", \"lastName\": \"Doe\"};\n * var keysMap = {\"firstName\": \"name\", \"lastName\": \"surname\"};\n *\n * _.rename(person, keysMap) // => {\"name\": \"John\", \"surname\": \"Doe\"}\n *\n * @example It's safe using it to swap keys:\n * var keysMap = {\"firstName\": \"lastName\", \"lastName\": \"firstName\"};\n *\n * _.rename(person, keysMap) // => {\"lastName\": \"John\", \"firstName\": \"Doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.renameKeys|renameKeys}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} source\n * @param {Object} keysMap\n * @returns {Object}\n */\n function rename (source, keysMap) {\n keysMap = Object(keysMap);\n var result = {};\n var oldKeys = enumerables(source);\n\n for (var prop in keysMap) {\n if (~oldKeys.indexOf(prop)) {\n result[keysMap[prop]] = source[prop];\n }\n }\n\n for (var i = 0, len = oldKeys.length, key; i < len; i++) {\n key = oldKeys[i];\n\n if (!(key in keysMap || key in result)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.rename|rename} expecting a\n * keysMap to build a function waiting for the object to act upon.\n * @example\n * var persons = [\n * {\"firstName\": \"John\", \"lastName\": \"Doe\"},\n * {\"first_name\": \"Mario\", \"last_name\": \"Rossi\"},\n * ];\n * var normalizeKeys = _.renameKeys({\n * \"firstName\": \"name\",\n * \"first_name\": \"name\",\n * \"lastName\": \"surname\",\n * \"last_name\": \"surname\"\n * });\n *\n * _.map(persons, normalizeKeys) // =>\n * // [\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} keysMap\n * @returns {Function}\n */\n var renameKeys = _curry2(rename, true);\n\n /**\n * Uses the provided function as a keysMap generator and returns\n * a function expecting the object whose keys we want to {@link module:lamb.rename|rename}.\n * @example\n * var person = {\"NAME\": \"John\", \"SURNAME\": \"Doe\"};\n * var arrayToLower = _.mapWith(_.invoker(\"toLowerCase\"));\n * var makeLowerKeysMap = function (source) {\n * var sourceKeys = _.keys(source);\n *\n * return _.make(sourceKeys, arrayToLower(sourceKeys));\n * };\n * var lowerKeysFor = _.renameWith(makeLowerKeysMap);\n *\n * lowerKeysFor(person) // => {\"name\": \"John\", \"surname\": \"doe\"};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameKeys|renameKeys}\n * @since 0.26.0\n * @param {Function} fn\n * @returns {Function}\n */\n function renameWith (fn) {\n return function (source) {\n return rename(source, fn(source));\n };\n }\n\n /**\n * Returns a copy of the source object without the specified properties.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.skip(user, [\"name\", \"age\"]) // => {surname: \"doe\"};\n * _.skip(user, [\"name\", \"email\"]) // => {surname: \"doe\", age: 30};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.skipKeys|skipKeys}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\n function skip (source, blacklist) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n var props = make(blacklist, []);\n\n for (var key in source) {\n if (!(key in props)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be omitted in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var skipIfIstring = _.skipIf(_.isType(\"String\"));\n *\n * skipIfIstring(user) // => {age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n var skipIf = compose(pickIf, not);\n\n /**\n * A curried version of {@link module:lamb.skip|skip}, expecting a blacklist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.skipKeys([\"name\", \"surname\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var discard = _.compose(_.mapWith, _.skipKeys);\n * var discardNames = discard([\"name\", \"surname\"]);\n *\n * discardNames(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.35.0\n * @param {String[]} blacklist\n * @returns {Function}\n */\n var skipKeys = _curry2(skip, true);\n\n /**\n * Tears an object apart by transforming it in an array of two lists: one containing\n * its enumerable keys, the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source\n * object will be unharmed.\n * @example\n * _.tear({a: 1, b: 2, c: 3}) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tearOwn|tearOwn}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tear = _tearFrom(enumerables);\n\n /**\n * Same as {@link module:lamb.tear|tear}, but only the own properties of the object are\n * taken into account.\n * @example Showing the difference with tear:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.tear(foo) // => [[\"c\", \"b\", \"a\"], [3, 2, 1]]\n * _.tearOwn(foo) // => [[\"c\"], [3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tear|tear}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tearOwn = _tearFrom(keys);\n\n /**\n * Generates an array with the values of the enumerable properties of the given object.
\n * See also {@link module:lamb.ownValues|ownValues} to pick only from the own properties of the object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.values(user) // => [\"john\", \"doe\", 30]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownValues|ownValues}\n * @since 0.1.0\n * @param {Object} obj\n * @returns {Array}\n */\n var values = _valuesFrom(enumerables);\n\n lamb.enumerables = enumerables;\n lamb.fromPairs = fromPairs;\n lamb.immutable = immutable;\n lamb.keys = keys;\n lamb.make = make;\n lamb.mapValues = mapValues;\n lamb.mapValuesWith = mapValuesWith;\n lamb.merge = merge;\n lamb.mergeOwn = mergeOwn;\n lamb.ownPairs = ownPairs;\n lamb.ownValues = ownValues;\n lamb.pairs = pairs;\n lamb.pick = pick;\n lamb.pickIf = pickIf;\n lamb.pickKeys = pickKeys;\n lamb.rename = rename;\n lamb.renameKeys = renameKeys;\n lamb.renameWith = renameWith;\n lamb.skip = skip;\n lamb.skipIf = skipIf;\n lamb.skipKeys = skipKeys;\n lamb.tear = tear;\n lamb.tearOwn = tearOwn;\n lamb.values = values;\n\n /**\n * Builds a checker function meant to be used with\n * {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to\n * compare their values. In other words all the received keyPaths will be\n * passed as arguments to the predicate to run the test.
\n * If you want to run the same single property check with multiple properties, you should build\n * multiple checkers and combine them with {@link module:lamb.validate|validate}.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\",\n * passwordConfirm: \"abc123\"\n * }\n * };\n * var pwdMatch = _.checker(\n * _.is,\n * \"Passwords don't match\",\n * [\"login.password\", \"login.passwordConfirm\"]\n * );\n *\n * pwdMatch(user) // => []\n *\n * var newUser = _.setPathIn(user, \"login.passwordConfirm\", \"avc123\");\n *\n * pwdMatch(newUser) // => [\"Passwords don't match\", [\"login.password\", \"login.passwordConfirm\"]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}, {@link module:lamb.validateWith|validateWith}\n * @since 0.1.0\n * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of keys, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Function} A checker function which returns an error in the form\n * [\"message\", [\"propertyA\", \"propertyB\"]] or an empty array.\n */\n function checker (predicate, message, keyPaths, pathSeparator) {\n return function (obj) {\n var getValues = partial(getPathIn, [obj, _, pathSeparator]);\n\n return predicate.apply(obj, map(keyPaths, getValues)) ? [] : [message, keyPaths];\n };\n }\n\n /**\n * Verifies the existence of a property in an object.\n * @example\n * var user1 = {name: \"john\"};\n *\n * _.has(user1, \"name\") // => true\n * _.has(user1, \"surname\") // => false\n * _.has(user1, \"toString\") // => true\n *\n * var user2 = Object.create(null);\n *\n * // not inherited through the prototype chain\n * _.has(user2, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function has (obj, key) {\n if (typeof obj !== \"object\" && !isUndefined(obj)) {\n obj = Object(obj);\n }\n\n return key in obj;\n }\n\n /**\n * Curried version of {@link module:lamb.has|has}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {};\n * var hasName = _.hasKey(\"name\");\n *\n * hasName(user1) // => true\n * hasName(user2) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.has|has}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasKey = _curry2(has, true);\n\n /**\n * Builds a predicate expecting an object to check against the given key / value pair.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var hasTheCorrectAnswer = _.hasKeyValue(\"answer\", 42);\n *\n * hasTheCorrectAnswer({answer: 2}) // false\n * hasTheCorrectAnswer({answer: 42}) // true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasPathValue|hasPathValue}\n * @since 0.1.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n function hasKeyValue (key, value) {\n return function (obj) {\n return isUndefined(value) ? has(obj, key) && obj[key] === value : areSVZ(value, obj[key]);\n };\n }\n\n /**\n * Verifies if an object has the specified property and that the property isn't inherited through\n * the prototype chain.
\n * @example Comparison with has:\n * var user = {name: \"john\"};\n *\n * _.has(user, \"name\") // => true\n * _.has(user, \"surname\") // => false\n * _.has(user, \"toString\") // => true\n *\n * _.hasOwn(user, \"name\") // => true\n * _.hasOwn(user, \"surname\") // => false\n * _.hasOwn(user, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var hasOwn = generic(_objectProto.hasOwnProperty);\n\n /**\n * Curried version of {@link module:lamb.hasOwn|hasOwn}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user = {name: \"john\"};\n * var hasOwnName = _.hasOwnKey(\"name\");\n * var hasOwnToString = _.hasOwnToString(\"toString\");\n *\n * hasOwnName(user) // => true\n * hasOwnToString(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwn|hasOwn}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasOwnKey = _curry2(hasOwn, true);\n\n /**\n * Builds a predicate to check if the given path exists in an object and holds the desired value.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * personal: {\n * age: 25,\n * gender: \"M\"\n * },\n * scores: [\n * {id: 1, value: 10, passed: false},\n * {id: 2, value: 20, passed: false},\n * {id: 3, value: 30, passed: true}\n * ]\n * };\n *\n * var isMale = _.hasPathValue(\"personal.gender\", \"M\");\n * var hasPassedFirstTest = _.hasPathValue(\"scores.0.passed\", true);\n * var hasPassedLastTest = _.hasPathValue(\"scores.-1.passed\", true);\n *\n * isMale(user) // => true\n * hasPassedFirstTest(user) // => false\n * hasPassedLastTest(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKeyValue|hasKeyValue}\n * @since 0.41.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function hasPathValue (path, value, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return pathInfo.isValid && areSVZ(pathInfo.target, value);\n };\n }\n\n /**\n * Builds a predicate to check if the given key satisfies the desired condition\n * on an object.\n * @example\n * var users = [\n * {name: \"John\", age: 25},\n * {name: \"Jane\", age: 15},\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n *\n * isAdult(users[0]) // => true\n * isAdult(users[1]) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathSatisfies|pathSatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} key\n * @returns {Function}\n */\n function keySatisfies (predicate, key) {\n return function (obj) {\n return predicate.call(this, obj[key]);\n };\n }\n\n /**\n * Builds a partial application of {@link module:lamb.pathExistsIn|pathExistsIn} using the given\n * path and the optional separator. The resulting function expects the object to check.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * var hasCity = _.pathExists(\"address.city\");\n * var hasCountry = _.pathExists(\"address.country\");\n * var hasAtLeastThreeScores = _.pathExists(\"scores.2\");\n *\n * hasCity(user) // => true\n * hasCountry(user) // => false\n * hasAtLeastThreeScores(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var pathExists = _makePartial3(pathExistsIn);\n\n /**\n * Checks if the provided path exists in the given object.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * _.pathExistsIn(user, \"address.city\") // => true\n * _.pathExistsIn(user, \"address.country\") // => false\n * _.pathExistsIn(user, \"scores.1\") // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathExists|pathExists}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {Object} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Boolean}\n */\n function pathExistsIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).isValid;\n }\n\n /**\n * Builds a predicate that verifies if a condition is satisfied for the given\n * path in an object.
\n * Like the other \"path functions\" you can use integers in the path, even\n * negative ones, to refer to array-like object indexes, but the priority will\n * be given to existing object keys.\n * @example\n * var user = {\n * name: \"John\",\n * performance: {\n * scores: [1, 5, 10]\n * }\n * };\n *\n * var gotAnHighScore = _.pathSatisfies(_.contains(10), \"performance.scores\");\n * var hadAGoodStart = _.pathSatisfies(_.isGT(6), \"performance.scores.0\");\n *\n * gotAnHighScore(user) // => true\n * hadAGoodStart(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.keySatisfies|keySatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function pathSatisfies (predicate, path, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return predicate.call(this, pathInfo.target);\n };\n }\n\n /**\n * Validates an object with the given list of {@link module:lamb.checker|checker} functions.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * _.validate(user1, userCheckers) // => []\n * _.validate(user2, userCheckers) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by\n * {@link module:lamb.checker|checker}, or an empty array.\n */\n function validate (obj, checkers) {\n return reduce(checkers, function (errors, _checker) {\n var result = _checker(obj);\n\n result.length && errors.push(result);\n\n return errors;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of\n * {@link module:lamb.checker|checkers} and returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n * var validateUser = _.validateWith(userCheckers);\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * validateUser(user1) // => []\n * validateUser(user2) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Function[]} checkers\n * @returns {Function}\n */\n var validateWith = _curry2(validate, true);\n\n lamb.checker = checker;\n lamb.has = has;\n lamb.hasKey = hasKey;\n lamb.hasKeyValue = hasKeyValue;\n lamb.hasOwn = hasOwn;\n lamb.hasOwnKey = hasOwnKey;\n lamb.hasPathValue = hasPathValue;\n lamb.keySatisfies = keySatisfies;\n lamb.pathExists = pathExists;\n lamb.pathExistsIn = pathExistsIn;\n lamb.pathSatisfies = pathSatisfies;\n lamb.validate = validate;\n lamb.validateWith = validateWith;\n\n /**\n * Pads a string to the desired length with the given char starting from the beginning of the string.\n * @example\n * _.padLeft(\"foo\", \"-\", 0) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", -1) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", 5) // => \"--foo\"\n * _.padLeft(\"foo\", \"-\", 3) // => \"foo\"\n * _.padLeft(\"foo\", \"ab\", 7) // => \"aaaafoo\"\n * _.padLeft(\"foo\", \"\", 5) // => \"foo\"\n * _.padLeft(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padRight|padRight}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padLeft (source, char, len) {\n return _getPadding(source, char, len) + source;\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the end of the string.\n * @example\n * _.padRight(\"foo\", \"-\", 0) // => \"foo\"\n * _.padRight(\"foo\", \"-\", -1) // => \"foo\"\n * _.padRight(\"foo\", \"-\", 5) // => \"foo--\"\n * _.padRight(\"foo\", \"-\", 3) // => \"foo\"\n * _.padRight(\"foo\", \"ab\", 7) // => \"fooaaaa\"\n * _.padRight(\"foo\", \"\", 5) // => \"foo\"\n * _.padRight(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padLeft|padLeft}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padRight (source, char, len) {\n return source + _getPadding(source, char, len);\n }\n\n /**\n * Builds a new string by repeating the source string the desired amount of times.
\n * Note that unlike the current ES6 proposal for\n * [String.prototype.repeat]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat},\n * this function doesn't throw a RangeError if times is negative,\n * but returns an empty string instead.\n * @example\n * _.repeat(\"Hello\", -1) // => \"\"\n * _.repeat(\"Hello\", 1) // => \"Hello\"\n * _.repeat(\"Hello\", 3) // => \"HelloHelloHello\"\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function repeat (source, times) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"string\");\n }\n\n return _repeat(source, Math.floor(times));\n }\n\n /**\n * Builds a predicate expecting a string to test against the given regular expression pattern.\n * @example\n * var hasNumbersOnly = _.testWith(/^\\d+$/);\n *\n * hasNumbersOnly(\"123\") // => true\n * hasNumbersOnly(\"123 Kg\") // => false\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {RegExp} pattern\n * @returns {Function}\n */\n function testWith (pattern) {\n return function (s) {\n return _search(s, pattern) !== -1;\n };\n }\n\n lamb.padLeft = padLeft;\n lamb.padRight = padRight;\n lamb.repeat = repeat;\n lamb.testWith = testWith;\n\n /* istanbul ignore next */\n if (typeof exports === \"object\") {\n module.exports = lamb;\n } else if (typeof define === \"function\" && define.amd) {\n define(function () {\n return lamb;\n });\n } else {\n host.lamb = lamb;\n }\n})(this);\n\n/**\n * @callback AccumulatorCallback\n * @global\n * @param {*} previousValue - The value returned it the last execution of the accumulator or, in the first\n * iteration, the {@link module:lamb.reduce|initialValue} if supplied.\n * @param {*} currentValue - The value being processed in the current iteration.\n * @param {Number} idx - The index of the element being processed.\n * @param {ArrayLike} arrayLike - The list being traversed.\n */\n\n/**\n * The built-in arguments object.\n * @typedef {arguments} arguments\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments|arguments} in Mozilla documentation.\n */\n\n/**\n * The built-in Array object.\n * @typedef {Array} Array\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array|Array} in Mozilla documentation.\n */\n\n/**\n * Any array-like object.\n * @typedef {Array|String|arguments|?} ArrayLike\n * @global\n */\n\n/**\n * The built-in Boolean object.\n * @typedef {Boolean} Boolean\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean|Boolean} in Mozilla documentation.\n */\n\n/**\n * The built-in Date object.\n * @typedef {Date} Date\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date|Date} in Mozilla documentation.\n */\n\n/**\n * The built-in Function object.\n * @typedef {Function} function\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function|Function} and\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions|Functions} in Mozilla documentation.\n */\n\n/**\n * @callback ListIteratorCallback\n * @global\n * @param {*} element - The element being evaluated.\n * @param {Number} idx - The index of the element within the list.\n * @param {ArrayLike} arrayLike - The list being traversed.\n */\n\n/**\n * The built-in Number object.\n * @typedef {Number} Number\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number|Number} in Mozilla documentation.\n */\n\n/**\n * The built-in Object object.\n * @typedef {Object} Object\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object|Object} in Mozilla documentation.\n */\n\n/**\n * @callback ObjectIteratorCallback\n * @global\n * @param {*} value - The value of the current property.\n * @param {String} key - The property name.\n * @param {Object} source - The object being traversed.\n */\n\n/**\n * The built-in RegExp object.\n * @typedef {RegExp} RegExp\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp|RegExp} in Mozilla documentation.\n */\n\n/**\n * Represents a sorting criteria used by {@link module:lamb.sortedInsert|sortedInsert},\n * {@link module:lamb.sort|sort} and {@link module:lamb.sortWith|sortWith}, and it's\n * usually built using {@link module:lamb.sorter|sorter} and {@link module:lamb.sorterDesc|sorterDesc}.\n * @typedef {Sorter} Sorter\n * @global\n * @property {Boolean} isDescending\n * @property {Function} compare\n */\n\n/**\n * The built-in String object.\n * @typedef {String} String\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String|String} in Mozilla documentation.\n */\n\n/**\n * The built-in primitive value undefined\n * @typedef {Undefined} Undefined\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined|undefined} in Mozilla documentation.\n */\n"]} \ No newline at end of file +{"version":3,"sources":["lamb.js"],"names":["host","lamb","Object","create","_","_placeholder","defineProperties","@@lamb/placeholder","get","set","value","@@lamb/version","_objectProto","prototype","_stringProto","String","MAX_ARRAY_LENGTH","compose","functions","arguments","len","length","idx","result","apply","this","call","identity","generic","Function","bind","partial","fn","args","Array","isArray","boundArg","lastIdx","newArgs","argsLen","i","_isPlaceholder","always","partialRight","boundArgs","j","_argsTail","_argsToArrayFrom","_comparer","a","b","areSVZ","_compareWith","criteria","criterion","compare","index","isDescending","_curry","arity","isRightCurry","isAutoCurry","_currier","argsHolder","holderLen","newArgsLen","reverse","_curry2","c","_forceToNumber","n","_getNumConsecutiveHits","arrayLike","predicate","_getPadding","source","char","isNil","type","_repeat","Math","ceil","_getPathInfo","obj","parts","walkNonEnumerables","_makeTypeErrorFor","key","target","isUndefined","_getPathKey","isValid","includeNonEnumerables","_isEnumerable","_groupWith","makeValue","iteratee","element","_invoker","methodName","method","boundArgsLen","ofs","_isOwnEnumerable","_safeEnumerables","indexOf","propertyIsEnumerable","_keyToPairIn","_makeArrayChecker","defaultResult","_makeArrayFlattener","isDeep","array","_flatten","output","vLen","slice","_makeCriteria","sorters","map","_makeCriterion","_sorter","_makePartial3","shouldAritize","binary","_makeReducer","step","accumulator","initialValue","nCalls","_toArrayLength","TypeError","desiredType","toLowerCase","_merge","getKeys","reduce","forEach","_pairsFrom","times","push","_safeKeys","keys","_search","search","_setIn","prop","_setIndex","updater","_toNaturalIndex","_setPathIn","v","partsLen","targetKey","reader","comparer","_tearFrom","clamp","_toInteger","floor","abs","NaN","_toPathParts","path","separator","split","_unsafeKeyListFrom","_valuesFrom","getIn","contains","isIn","everyIn","every","filter","filterWith","find","findIndex","findIndexWhere","findWhere","list","mapWith","reduceRight","reduceRightWith","reduceWith","start","end","begin","upTo","resultLen","sliceAt","someIn","some","areSame","gt","gte","is","isGT","isGTE","isLT","lt","isLTE","lte","isSVZ","not","adapter","allOf","predicates","anyOf","case","condition","trueFn","falseFn","unless","when","add","sum","min","max","clampWithin","deduct","subtract","divide","divideBy","isInteger","multiply","multiplyBy","isNull","toString","generate","limit","isFinite","isSafeInteger","modulo","randomInt","random","range","last","remainder","isInstanceOf","constructor","isType","typeName","getAt","getIndex","getKey","getPath","getPathIn","head","setAt","setIn","setIndex","aritize","setKey","setPathIn","updateIn","enumerables","updateIndex","updateKey","updatePathIn","pathInfo","setPath","updateAt","updatePath","append","appendTo","concat","drop","dropFrom","flatMap","el","arr","rLen","flatMapWith","flatten","init","insert","splice","insertAt","partition","partitionWith","pluckKey","pull","pullFrom","values","shallowFlatten","tail","take","takeFrom","transpose","minLen","elementLen","union","unionBy","uniquesBy","uniques","seen","hasNaN","zip","zipWithIndex","difference","other","isNotInOther","dropWhile","intersection","rest","item","pluck","takeWhile","count","countBy","group","groupBy","indexBy","sort","sorter","sorterDesc","application","sortedInsert","_getInsertionIndex","pivot","sortWith","applyTo","flip","pipe","asPartial","_asPartial","collect","curry","curryRight","curryable","curryableRight","debounce","timespan","timeoutID","debounced","clearTimeout","setTimeout","getArgAt","invoker","invokerOn","mapArgs","mapper","tapArgs","tappers","tappersLen","throttle","lastCall","now","Date","unary","make","names","valuesLen","mapValues","mapValuesWith","merge","mergeOwn","ownPairs","ownValues","pairs","pick","whitelist","has","pickIf","pickKeys","rename","keysMap","oldKeys","renameKeys","skip","blacklist","props","skipIf","skipKeys","tear","tearOwn","fromPairs","pairsList","pair","immutable","_immutable","freeze","getOwnPropertyNames","renameWith","hasKey","hasOwn","hasOwnProperty","hasOwnKey","pathExists","pathExistsIn","validate","checkers","errors","_checker","validateWith","checker","message","keyPaths","pathSeparator","getValues","hasKeyValue","hasPathValue","keySatisfies","pathSatisfies","padLeft","padRight","repeat","testWith","pattern","s","exports","module","define","amd"],"mappings":"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","file":"lamb.min.js","sourcesContent":["/**\n * @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming.\n * @author Andrea Scartabelli \n * @version 0.55.0-alpha.4\n * @module lamb\n * @license MIT\n * @preserve\n */\n(function (host) {\n \"use strict\";\n\n var lamb = Object.create(null);\n var _ = {}; // internal placeholder for partial application\n var _placeholder = lamb; // default value for public placeholder\n\n Object.defineProperties(lamb, {\n /**\n * The object used as a placeholder in partial application. Its default value is\n * the lamb object itself.
\n * The property is public so that you can make Lamb use your own placeholder, however\n * you can't change it at will or the partially applied functions you defined before the\n * change won't recognize the former placeholder.\n * @memberof module:lamb\n * @category Special properties\n * @alias @@lamb/placeholder\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.53.0\n * @type Object\n */\n \"@@lamb/placeholder\": {\n get: function () {\n return _placeholder;\n },\n set: function (value) {\n _placeholder = value;\n }\n },\n\n /**\n * The current library version.\n * @memberof module:lamb\n * @category Special properties\n * @alias @@lamb/version\n * @readonly\n * @since 0.53.0\n * @type String\n */\n \"@@lamb/version\": {value: \"0.55.0-alpha.4\"}\n });\n\n // prototype shortcuts\n var _objectProto = Object.prototype;\n var _stringProto = String.prototype;\n\n // constants\n var MAX_ARRAY_LENGTH = 4294967295;\n\n /**\n * Builds a function that returns a constant value.\n * It's actually the simplest form of the K combinator or Kestrel.\n * @example\n * var truth = _.always(true);\n *\n * truth() // => true\n * truth(false) // => true\n * truth(1, 2) // => true\n *\n * // the value being returned is actually the\n * // very same value passed to the function\n * var foo = {bar: \"baz\"};\n * var alwaysFoo = _.always(foo);\n *\n * alwaysFoo() === foo // => true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n function always (value) {\n return function () {\n return value;\n };\n }\n\n /**\n * Returns a function that is the composition of the functions given as parameters.\n * Each function consumes the result of the function that follows.\n * @example\n * var sayHi = function (name) { return \"Hi, \" + name; };\n * var capitalize = function (s) {\n * return s[0].toUpperCase() + s.substr(1).toLowerCase();\n * };\n * var fixNameAndSayHi = _.compose(sayHi, capitalize);\n *\n * sayHi(\"bOb\") // => \"Hi, bOb\"\n * fixNameAndSayHi(\"bOb\") // \"Hi, Bob\"\n *\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, _.getKey(\"name\"));\n *\n * _.map(users, sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.pipe|pipe}\n * @since 0.1.0\n * @param {...Function} fn\n * @returns {Function}\n */\n function compose () {\n var functions = arguments;\n var len = functions.length;\n\n return len ? function () {\n var idx = len - 1;\n var result = functions[idx].apply(this, arguments);\n\n while (idx--) {\n result = functions[idx].call(this, result);\n }\n\n return result;\n } : identity;\n }\n\n /**\n * Creates generic functions out of methods.\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}.\n * Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @memberof module:lamb\n * @category Function\n * @function\n * @example\n * var join = _.generic(Array.prototype.join);\n *\n * join([1, 2, 3, 4, 5], \"-\") // => \"1-2-3-4-5\"\n *\n * // the function will work with any array-like object\n * join(\"hello\", \"-\") // => \"h-e-l-l-o\"\n *\n * @since 0.1.0\n * @param {Function} method\n * @returns {Function}\n */\n var generic = Function.bind.bind(Function.call);\n\n /**\n * The I combinator. Any value passed to the function is simply returned as it is.\n * @example\n * var foo = {bar: \"baz\"};\n *\n * _.identity(foo) === foo // true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {*} The value passed as parameter.\n */\n function identity (value) {\n return value;\n }\n\n /**\n * Builds a partially applied function. The lamb object itself can be\n * used as a placeholder argument and it's useful to alias it with a short symbol\n * such as _.
\n * You can use a custom placeholder by setting the\n * {@link module:lamb.@@lamb/placeholder|@@lamb/placeholder} property.\n * @example\n * var users = [\n * {id: 1, name: \"John\", active: true, confirmedMail: true},\n * {id: 2, name: \"Jane\", active: true, confirmedMail: false},\n * {id: 3, name: \"Mario\", active: false, confirmedMail: false}\n * ];\n * var isKeyTrue = _.partial(_.hasKeyValue, [_, true]);\n * var isActive = isKeyTrue(\"active\");\n * var hasConfirmedMail = isKeyTrue(\"confirmedMail\");\n *\n * _.map(users, isActive) // => [true, true, false]\n * _.map(users, hasConfirmedMail) // => [true, false, false]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.@@lamb/placeholder|@@lamb/placeholder}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Array} args\n * @returns {Function}\n */\n function partial (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = 0;\n var newArgs = [];\n var argsLen = args.length;\n\n for (var i = 0, boundArg; i < argsLen; i++) {\n boundArg = args[i];\n newArgs[i] = _isPlaceholder(boundArg) ? arguments[lastIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastIdx < len; lastIdx++) {\n newArgs[i++] = arguments[lastIdx];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Like {@link module:lamb.partial|partial} will build a partially applied function and\n * it will accept placeholders.
\n * The difference is that the bound arguments will be appended to the ones received by\n * the resulting function.\n * @example\n * Explaining the difference with partial:\n * var f1 = _.partial(_.list, [\"a\", \"b\", \"c\"]);\n * var f2 = _.partialRight(_.list, [\"a\", \"b\", \"c\"]);\n *\n * f1(\"d\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"d\", \"e\") // => [\"d\", \"e\", \"a\", \"b\", \"c\"]\n *\n * @example\n * Explaining placeholder substitutions:\n * var f1 = _.partial(_.list, [\"a\", _, _, \"d\"]);\n * var f2 = _.partialRight(_.list, [\"a\", _, _, \"d\"]);\n *\n * f1(\"b\", \"c\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"b\", \"c\", \"e\") // => [\"b\", \"a\", \"c\", \"e\", \"d\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.@@lamb/placeholder|@@lamb/placeholder}\n * @param {Function} fn\n * @param {Array} args\n * @since 0.52.0\n * @returns {Function}\n */\n function partialRight (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = arguments.length - 1;\n var argsLen = args.length;\n var boundArgs = Array(argsLen);\n var newArgs = [];\n\n for (var i = argsLen - 1, boundArg; i > -1; i--) {\n boundArg = args[i];\n boundArgs[i] = _isPlaceholder(boundArg) ? arguments[lastIdx--] : boundArg;\n }\n\n for (i = 0; i <= lastIdx; i++) {\n newArgs[i] = arguments[i];\n }\n\n for (var j = 0; j < argsLen; j++) {\n newArgs[i++] = boundArgs[j];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n lamb.always = always;\n lamb.compose = compose;\n lamb.generic = generic;\n lamb.identity = identity;\n lamb.partial = partial;\n lamb.partialRight = partialRight;\n\n /**\n * Builds an array with the received arguments excluding the first one.
\n * To be used with the arguments object, which needs to be passed to the apply\n * method of this function.\n * @private\n * @function\n * @param {...*} value\n * @returns {Array}\n */\n var _argsTail = _argsToArrayFrom(1);\n\n /**\n * Builds helper functions to extract portions of the arguments\n * object rather efficiently without having to write for loops\n * manually for each case.
\n * The arguments object needs to be passed to the apply method\n * of the generated function.\n * @private\n * @param {Number} idx\n * @returns {Function}\n */\n function _argsToArrayFrom (idx) {\n return function () {\n var argsLen = arguments.length || idx;\n var len = argsLen - idx;\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = arguments[i + idx];\n }\n\n return result;\n };\n }\n\n /**\n * Keeps building a partial application of the received function as long\n * as it's called with placeholders; applies the original function to\n * the collected parameters otherwise.
\n * The function checks only the public placeholder to gain a little performance\n * as no function in Lamb is built with {@link module:lamb.asPartial|asPartial}.\n * @private\n * @param {Function} fn\n * @param {Array} argsHolder\n * @returns {Function|*}\n */\n function _asPartial (fn, argsHolder) {\n return function () {\n var argsLen = arguments.length;\n var lastIdx = 0;\n var newArgs = [];\n\n for (var i = 0, len = argsHolder.length, boundArg; i < len; i++) {\n boundArg = argsHolder[i];\n newArgs[i] = boundArg === _placeholder && lastIdx < argsLen ? arguments[lastIdx++] : boundArg;\n }\n\n while (lastIdx < argsLen) {\n newArgs[i++] = arguments[lastIdx++];\n }\n\n for (i = 0; i < argsLen; i++) {\n if (arguments[i] === _placeholder) {\n return _asPartial(fn, newArgs);\n }\n }\n\n for (i = 0, len = newArgs.length; i < len; i++) {\n if (newArgs[i] === _placeholder) {\n newArgs[i] = void 0;\n }\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * The default comparer for sorting functions.
\n * If the given values are of different types they\n * will be both converted to strings.
\n * Uses the SameValueZero comparison.\n * @private\n * @param {*} a\n * @param {*} b\n * @returns {Number} -1 | 0 | 1\n */\n function _comparer (a, b) {\n var result = 0;\n\n if (typeof a !== typeof b) {\n a = String(a);\n b = String(b);\n }\n\n /* eslint-disable no-self-compare */\n\n if (!areSVZ(a, b)) {\n if (a > b || a !== a) {\n result = 1;\n } else if (a < b || b !== b) {\n result = -1;\n }\n }\n\n /* eslint-enable no-self-compare */\n\n return result;\n }\n\n /**\n * Accepts a list of sorting criteria with at least one element\n * and builds a function that compares two values with such criteria.\n * @private\n * @param {Sorter[]} criteria\n * @returns {Function}\n */\n function _compareWith (criteria) {\n return function (a, b) {\n var len = criteria.length;\n var criterion = criteria[0];\n var result = criterion.compare(a.value, b.value);\n\n for (var i = 1; result === 0 && i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n }\n\n if (result === 0) {\n result = a.index - b.index;\n }\n\n return criterion.isDescending ? -result : result;\n };\n }\n\n /**\n * Used by curry functions to collect arguments until the arity is consumed,\n * then applies the original function.\n * @private\n * @param {Function} fn\n * @param {Number} arity\n * @param {Boolean} isRightCurry\n * @param {Boolean} isAutoCurry\n * @param {Array} argsHolder\n * @returns {Function}\n */\n function _currier (fn, arity, isRightCurry, isAutoCurry, argsHolder) {\n return function () {\n var holderLen = argsHolder.length;\n var argsLen = arguments.length;\n var newArgsLen = holderLen + (argsLen > 1 && isAutoCurry ? argsLen : 1);\n var newArgs = Array(newArgsLen);\n\n for (var i = 0; i < holderLen; i++) {\n newArgs[i] = argsHolder[i];\n }\n\n for (; i < newArgsLen; i++) {\n newArgs[i] = arguments[i - holderLen];\n }\n\n if (newArgsLen >= arity) {\n return fn.apply(this, isRightCurry ? newArgs.reverse() : newArgs);\n } else {\n return _currier(fn, arity, isRightCurry, isAutoCurry, newArgs);\n }\n };\n }\n\n /**\n * Prepares a function for currying. If it's not auto-currying and the arity\n * is 2 or 3 returns optimized functions, otherwise delegates the currying\n * to the _currier function.
\n * If the desumed arity isn't greater than one, it will return the received\n * function itself, instead.\n * @private\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @param {Boolean} [isRightCurry=false]\n * @param {Boolean} [isAutoCurry=false]\n * @returns {Function}\n */\n function _curry (fn, arity, isRightCurry, isAutoCurry) {\n if (arity >>> 0 !== arity) {\n arity = fn.length;\n }\n\n if (isAutoCurry && arity > 1 || arity > 3) {\n return _currier(fn, arity, isRightCurry, isAutoCurry, []);\n } else if (arity === 2) {\n return _curry2(fn, isRightCurry);\n } else if (arity === 3) {\n return _curry3(fn, isRightCurry);\n } else {\n return fn;\n }\n }\n\n /**\n * Curries a function of arity 2.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry2 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return isRightCurry ? fn.call(this, b, a) : fn.call(this, a, b);\n };\n };\n }\n\n /**\n * Curries a function of arity 3.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry3 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return function (c) {\n return isRightCurry ? fn.call(this, c, b, a) : fn.call(this, a, b, c);\n };\n };\n };\n }\n\n /**\n * Flattens an array.\n * @private\n * @param {Array} array - The source array\n * @param {Boolean} isDeep - Whether to perform a deep flattening or not\n * @param {Array} output - An array to collect the result\n * @param {Number} idx - The next index to be filled in the output\n * @returns {Array} The output array filled with the results\n */\n function _flatten (array, isDeep, output, idx) {\n for (var i = 0, len = array.length, value, j, vLen; i < len; i++) {\n value = array[i];\n\n if (!Array.isArray(value)) {\n output[idx++] = value;\n } else if (isDeep) {\n _flatten(value, true, output, idx);\n idx = output.length;\n } else {\n vLen = value.length;\n output.length += vLen;\n\n for (j = 0; j < vLen; j++) {\n output[idx++] = value[j];\n }\n }\n }\n\n return output;\n }\n\n /**\n * Converts a value to a number and returns it if it's not NaN, otherwise\n * returns zero.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _forceToNumber (value) {\n var n = +value;\n\n return n === n ? n : 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * Establishes at which index an element should be inserted in a sorted array to respect\n * the array order. Needs the comparer used to sort the array.\n * @private\n * @param {Array} array\n * @param {*} element\n * @param {Function} comparer\n * @param {Number} start\n * @param {Number} end\n * @returns {Number}\n */\n function _getInsertionIndex (array, element, comparer, start, end) {\n if (array.length === 0) {\n return 0;\n }\n\n var pivot = (start + end) >> 1;\n var result = comparer(\n {value: element, index: pivot},\n {value: array[pivot], index: pivot}\n );\n\n if (end - start <= 1) {\n return result < 0 ? pivot : pivot + 1;\n } else if (result < 0) {\n return _getInsertionIndex(array, element, comparer, start, pivot);\n } else if (result === 0) {\n return pivot + 1;\n } else {\n return _getInsertionIndex(array, element, comparer, pivot, end);\n }\n }\n\n /**\n * Gets the number of consecutive elements satisfying a predicate in an array-like object.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function _getNumConsecutiveHits (arrayLike, predicate) {\n var idx = 0;\n var len = arrayLike.length;\n\n while (idx < len && predicate(arrayLike[idx], idx, arrayLike)) {\n idx++;\n }\n\n return idx;\n }\n\n /**\n * Builds the prefix or suffix to be used when padding a string.\n * @private\n * @param {String} source\n * @param {String} char\n * @param {Number} len\n * @returns {String}\n */\n function _getPadding (source, char, len) {\n if (!isNil(source) && type(source) !== \"String\") {\n source = String(source);\n }\n\n return _repeat(String(char)[0] || \"\", Math.ceil(len - source.length));\n }\n\n /**\n * Checks if a path is valid in the given object and retrieves the path target.\n * @private\n * @param {Object} obj\n * @param {String[]} parts\n * @param {Boolean} walkNonEnumerables\n * @returns {Object}\n */\n function _getPathInfo (obj, parts, walkNonEnumerables) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n var target = obj;\n var i = -1;\n var len = parts.length;\n var key;\n\n while (++i < len) {\n key = _getPathKey(target, parts[i], walkNonEnumerables);\n\n if (isUndefined(key)) {\n break;\n }\n\n target = target[key];\n }\n\n return i === len ? {isValid: true, target: target} : {isValid: false, target: void 0};\n }\n\n /**\n * Helper to retrieve the correct key while evaluating a path.\n * @private\n * @param {Object} target\n * @param {String} key\n * @param {Boolean} includeNonEnumerables\n * @returns {String|Number|Undefined}\n */\n function _getPathKey (target, key, includeNonEnumerables) {\n if (includeNonEnumerables && key in Object(target) || _isEnumerable(target, key)) {\n return key;\n }\n\n var n = +key;\n var len = target && target.length;\n\n return n >= -len && n < len ? n < 0 ? n + len : n : void 0;\n }\n\n /**\n * Builds a \"grouping function\" for an array-like object.\n * @private\n * @param {Function} makeValue\n * @returns {Function}\n */\n function _groupWith (makeValue) {\n return function (arrayLike, iteratee) {\n var result = {};\n var len = arrayLike.length;\n\n for (var i = 0, element, key; i < len; i++) {\n element = arrayLike[i];\n key = iteratee(element, i, arrayLike);\n result[key] = makeValue(result[key], element);\n }\n\n return result;\n };\n }\n\n /**\n * Makes an object immutable by recursively calling Object.freeze\n * on its members.\n * @private\n * @param {Object} obj\n * @param {Array} seen\n * @returns {Object} The obj parameter itself, not a copy.\n */\n function _immutable (obj, seen) {\n if (seen.indexOf(obj) === -1) {\n seen.push(Object.freeze(obj));\n\n forEach(Object.getOwnPropertyNames(obj), function (key) {\n var value = obj[key];\n\n if (typeof value === \"object\" && !isNull(value)) {\n _immutable(value, seen);\n }\n });\n }\n\n return obj;\n }\n\n /**\n * If a method with the given name exists on the target, applies it to the provided\n * arguments and returns the result. Returns undefined otherwise.
\n * The arguments for the method are built by concatenating the array of bound arguments,\n * optionally received by {@link module:lamb.invoker|invoker}, with the final set of, also\n * optional, args.\n * @private\n * @param {Array} boundArgs\n * @param {String} methodName\n * @param {Object} target\n * @param {...*} [args]\n * @returns {*}\n */\n function _invoker (boundArgs, methodName, target) {\n var method = target[methodName];\n\n if (typeof method !== \"function\") {\n return void 0;\n }\n\n var boundArgsLen = boundArgs.length;\n var ofs = 3 - boundArgsLen;\n var len = arguments.length - ofs;\n var args = Array(len);\n\n for (var i = 0; i < boundArgsLen; i++) {\n args[i] = boundArgs[i];\n }\n\n for (; i < len; i++) {\n args[i] = arguments[i + ofs];\n }\n\n return method.apply(target, args);\n }\n\n /**\n * Accepts a target object and a key name and verifies that the target is an array and that\n * the key is an existing index.\n * @private\n * @param {Object} target\n * @param {String|Number} key\n * @returns {Boolean}\n */\n function _isArrayIndex (target, key) {\n var n = +key;\n\n return Array.isArray(target) && n % 1 === 0 && !(n < 0 && _isEnumerable(target, key));\n }\n\n /**\n * Checks whether the specified key is an enumerable property of the given object or not.\n * @private\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function _isEnumerable (obj, key) {\n return key in Object(obj) && (_isOwnEnumerable(obj, key) || ~_safeEnumerables(obj).indexOf(key));\n }\n\n /**\n * Checks whether the specified key is a own enumerable property of the given object or not.\n * @private\n * @function\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var _isOwnEnumerable = generic(_objectProto.propertyIsEnumerable);\n\n /**\n * Checks whether the given value is the internal or the public placeholder.\n * @private\n * @param {*} value\n * @returns {Boolean}\n */\n function _isPlaceholder (value) {\n return value === _ || value === _placeholder;\n }\n\n /**\n * Accepts an object and build a function expecting a key to create a \"pair\" with the key\n * and its value.\n * @private\n * @function\n * @param {Object} obj\n * @returns {Function}\n */\n var _keyToPairIn = _curry2(function (obj, key) {\n return [key, obj[key]];\n });\n\n /**\n * Helper to build the {@link module:lamb.everyIn|everyIn} or the\n * {@link module:lamb.someIn|someIn} function.\n * @private\n * @param {Boolean} defaultResult\n * @returns {Function}\n */\n function _makeArrayChecker (defaultResult) {\n return function (arrayLike, predicate) {\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (defaultResult ^ !!predicate(arrayLike[i], i, arrayLike)) {\n return !defaultResult;\n }\n }\n\n return defaultResult;\n };\n }\n\n /**\n * Helper to build the {@link module:lamb.flatten|flatten} and\n * {@link module:lamb.shallowFlatten|shallowFlatten} functions.\n * @private\n * @function\n * @param {Boolean} isDeep\n * @returns {Function}\n */\n var _makeArrayFlattener = _curry2(function (isDeep, array) {\n return Array.isArray(array) ? _flatten(array, isDeep, [], 0) : slice(array, 0, array.length);\n });\n\n /**\n * Builds a list of sorting criteria from a list of sorter functions. Returns a list containing\n * a single default sorting criterion if the sorter list is empty.\n * @private\n * @param {Function[]} sorters\n * @returns {Sorter[]}\n */\n function _makeCriteria (sorters) {\n return sorters.length ? map(sorters, _makeCriterion) : [_sorter()];\n }\n\n /**\n * Converts a sorting function to a sorting criterion if necessary.\n * @private\n * @param {Function} criterion\n * @returns {Sorter}\n */\n function _makeCriterion (criterion) {\n return criterion && typeof criterion.compare === \"function\" ? criterion : _sorter(criterion);\n }\n\n /**\n * Builds a partial application of a ternary function so that its first parameter\n * is expected as the last one.
\n * The shouldAritize parameter is for the \"reduce\" functions, where\n * the absence of the initialValue transforms a \"fold\" operation into a\n * \"reduce\" one.\n * @private\n * @param {Function} fn\n * @param {Boolean} shouldAritize\n * @returns {Function}\n */\n function _makePartial3 (fn, shouldAritize) {\n return function (a, b) {\n var f = shouldAritize && arguments.length !== 2 ? binary(fn) : fn;\n\n return partial(f, [_, a, b]);\n };\n }\n\n /**\n * Builds a reduce function. The step parameter must be 1\n * to build {@link module:lamb.reduce|reduce} and -1 to build\n * {@link module:lamb.reduceRight|reduceRight}.\n * @private\n * @param {Number} step\n * @returns {Function}\n */\n function _makeReducer (step) {\n return function (arrayLike, accumulator, initialValue) {\n var len = _toArrayLength(arrayLike.length);\n var idx = step === 1 ? 0 : len - 1;\n var nCalls;\n var result;\n\n if (arguments.length === 3) {\n nCalls = len;\n result = initialValue;\n } else {\n if (len === 0) {\n throw new TypeError(\"Reduce of empty array-like with no initial value\");\n }\n\n result = arrayLike[idx];\n idx += step;\n nCalls = len - 1;\n }\n\n for (; nCalls--; idx += step) {\n result = accumulator(result, arrayLike[idx], idx, arrayLike);\n }\n\n return result;\n };\n }\n\n /**\n * Builds a TypeError stating that it's not possible to convert the given value to the\n * desired type.\n * @private\n * @param {*} value\n * @param {String} desiredType\n * @returns {TypeError}\n */\n function _makeTypeErrorFor (value, desiredType) {\n return new TypeError(\"Cannot convert \" + type(value).toLowerCase() + \" to \" + desiredType);\n }\n\n /**\n * Merges the received objects using the provided function to retrieve their keys.\n * @private\n * @param {Function} getKeys\n * @param {...Object} source\n * @returns {Object}\n */\n function _merge (getKeys) {\n return reduce(_argsTail.apply(null, arguments), function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n }\n\n /**\n * Using the provided function to retrieve the keys, builds a new function\n * expecting an object to create a list of key / value pairs.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _pairsFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), _keyToPairIn(obj));\n });\n\n /**\n * A null-safe function to repeat the source string the desired amount of times.\n * @private\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function _repeat (source, times) {\n var result = \"\";\n\n for (var i = 0; i < times; i++) {\n result += source;\n }\n\n return result;\n }\n\n /**\n * Builds a list of the enumerable properties of an object.\n * The function is null-safe, unlike the public one.\n * @private\n * @param {Object} obj\n * @returns {String[]}\n */\n function _safeEnumerables (obj) {\n var result = [];\n\n for (var key in obj) {\n result.push(key);\n }\n\n return result;\n }\n\n /**\n * A null-safe version of Object.keys.\n * @private\n * @function\n * @param {Object} obj\n * @returns {String[]}\n */\n var _safeKeys = compose(Object.keys, Object);\n\n /**\n * A generic version of String.prototype.search\n * @private\n * @function\n * @param {String} s\n * @param {RegExp} pattern\n * @return {Number}\n */\n var _search = generic(_stringProto.search);\n\n /**\n * Sets, or creates, a property in a copy of the provided object to the desired value.\n * @private\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function _setIn (source, key, value) {\n var result = {};\n\n for (var prop in source) {\n result[prop] = source[prop];\n }\n\n result[key] = value;\n\n return result;\n }\n\n /**\n * Sets an index in an array-like object.
\n * If provided with an updater function it will use it to update the current value,\n * otherwise sets the index to the specified value.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {Number} idx\n * @param {*} [value]\n * @param {Function} [updater]\n * @returns {Array}\n */\n function _setIndex (arrayLike, idx, value, updater) {\n var result = slice(arrayLike, 0, arrayLike.length);\n var n = _toNaturalIndex(idx, result.length);\n\n if (n === n) { // eslint-disable-line no-self-compare\n result[n] = arguments.length === 4 ? updater(arrayLike[n]) : value;\n }\n\n return result;\n }\n\n /**\n * Sets the object's property targeted by the given path to the desired value.
\n * Works with arrays and is able to set their indexes, even negative ones.\n * @private\n * @param {Object|Array} obj\n * @param {String[]} parts\n * @param {*} value\n * @returns {Object|Array}\n */\n function _setPathIn (obj, parts, value) {\n var key = parts[0];\n var partsLen = parts.length;\n var v;\n\n if (partsLen === 1) {\n v = value;\n } else {\n var targetKey = _getPathKey(obj, key, false);\n\n v = _setPathIn(\n isUndefined(targetKey) ? targetKey : obj[targetKey],\n slice(parts, 1, partsLen),\n value\n );\n }\n\n return _isArrayIndex(obj, key) ? _setIndex(obj, key, v) : _setIn(obj, key, v);\n }\n\n /**\n * Builds a sorting criterion. If the comparer function is missing, the default\n * comparer will be used instead.\n * @private\n * @param {Function} reader\n * @param {Boolean} isDescending\n * @param {Function} [comparer]\n * @returns {Sorter}\n */\n function _sorter (reader, isDescending, comparer) {\n if (typeof reader !== \"function\" || reader === identity) {\n reader = null;\n }\n\n if (typeof comparer !== \"function\") {\n comparer = _comparer;\n }\n\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (reader) {\n a = reader(a);\n b = reader(b);\n }\n\n return comparer(a, b);\n }\n };\n }\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create an array containing a list\n * of the keys in its first index and the corresponding list of values\n * in the second one.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _tearFrom = _curry2(function (getKeys, obj) {\n return reduce(getKeys(obj), function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n\n return result;\n }, [[], []]);\n });\n\n /**\n * Converts a value to a valid array length, thus an integer within\n * 0 and 232 - 1 (both included).\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toArrayLength (value) {\n return clamp(value, 0, MAX_ARRAY_LENGTH) >>> 0;\n }\n\n /**\n * Converts a value to an integer.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toInteger (value) {\n var n = +value;\n\n if (n !== n) { // eslint-disable-line no-self-compare\n return 0;\n } else if (n % 1 === 0) {\n return n;\n } else {\n return Math.floor(Math.abs(n)) * (n < 0 ? -1 : 1);\n }\n }\n\n /**\n * Checks if the given number, even negative, represents an array-like index\n * within the provided length. If so returns its natural number equivalent.
\n * Returns NaN otherwise.\n * @private\n * @param {Number} idx\n * @param {Number} len\n * @returns {Number}\n */\n function _toNaturalIndex (idx, len) {\n idx = _toInteger(idx);\n\n return idx >= -len && idx < len ? idx < 0 ? idx + len : idx : NaN;\n }\n\n /**\n * Splits a sting path using the provided separator and returns an array\n * of path parts.\n * @private\n * @param {String} path\n * @param {String} separator\n * @returns {String[]}\n */\n function _toPathParts (path, separator) {\n return String(path).split(separator || \".\");\n }\n\n /**\n * Creates a non-null-safe version of the provided \"getKeys\" function.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _unsafeKeyListFrom = _curry2(function (getKeys, obj) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n return getKeys(obj);\n });\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create the list of values for such keys.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _valuesFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), partial(getIn, [obj]));\n });\n\n /**\n * Builds a predicate to check if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.isIn|isIn} for an uncurried version.\n * @example\n * var containsNaN = _.contains(NaN);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.isIn|isIn}\n * @since 0.13.0\n * @param {*} value\n * @returns {Function}\n */\n var contains = _curry2(isIn, true);\n\n /**\n * Checks if all the elements in an array-like object satisfy the given predicate.
\n * The function will stop calling the predicate as soon as it returns a falsy value.
\n * Note that an empty array-like will always produce a true result regardless of the\n * predicate because of [vacuous truth]{@link https://en.wikipedia.org/wiki/Vacuous_truth}.
\n * Also note that unlike the native\n * [Array.prototype.every]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: true},\n * {\"name\": \"John\", \"age\": 40, active: true},\n * {\"name\": \"Mario\", \"age\": 17, active: true},\n * {\"name\": \"Paolo\", \"age\": 15, active: true}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.everyIn(persons, isAdult) // => false\n * _.everyIn(persons, isActive) // => true\n *\n * @example Showing the difference with Array.prototype.every:\n * var isDefined = _.not(_.isUndefined);\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.every(isDefined) // => true\n * _.everyIn(arr, isDefined) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.every|every}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var everyIn = _makeArrayChecker(true);\n\n /**\n * A curried version of {@link module:lamb.everyIn|everyIn} that expects a predicate\n * to build a function waiting for the array-like to act upon.\n * @example\n * var data = [2, 3, 5, 6, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var allEvens = _.every(isEven);\n * var allIntegers = _.every(_.isInteger);\n *\n * allEvens(data) // => false\n * allIntegers(data) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.everyIn|everyIn}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var every = _curry2(everyIn, true);\n\n /**\n * Builds an array comprised of all values of the array-like object passing the predicate\n * test.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n *\n * _.filter([\"Foo\", \"bar\", \"baZ\"], isLowerCase) // => [\"bar\"]\n *\n * // the function will work with any array-like object\n * _.filter(\"fooBAR\", isLowerCase) // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.filterWith|filterWith}\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @since 0.1.0\n * @returns {Array}\n */\n function filter (arrayLike, predicate) {\n var len = arrayLike.length;\n var result = [];\n\n for (var i = 0; i < len; i++) {\n predicate(arrayLike[i], i, arrayLike) && result.push(arrayLike[i]);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.filter|filter} that uses the given predicate\n * to build a function expecting the array-like object to act upon.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n * var getLowerCaseEntries = _.filterWith(isLowerCase);\n *\n * getLowerCaseEntries([\"Foo\", \"bar\", \"baZ\"]) // => [\"bar\"]\n *\n * // array-like objects can be used as well\n * getLowerCaseEntries(\"fooBAR\") // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.filter|filter}\n * @since 0.9.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var filterWith = _curry2(filter, true);\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns it if\n * the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.find(persons, _.hasKeyValue(\"age\", 40)) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.find(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\n function find (arrayLike, predicate) {\n var idx = findIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns its\n * index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findIndex(persons, _.hasKeyValue(\"age\", 40)) // => 1\n * _.findIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function findIndex (arrayLike, predicate) {\n var result = -1;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (predicate(arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.findIndex|findIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEvenIdx = _.findIndexWhere(isEven);\n *\n * findEvenIdx([1, 3, 4, 5, 7]) // => 2\n * findEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findIndex|findIndex}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findIndexWhere = _curry2(findIndex, true);\n\n /**\n * A curried version of {@link module:lamb.find|find} expecting the array-like object\n * to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 7]) // => 4\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.find|find}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findWhere = _curry2(find, true);\n\n /**\n * Executes the provided iteratee for each element of the given array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment:\n * var addClass = _.curry(function (className, element) {\n * element.classList.add(className);\n * });\n * var paragraphs = document.querySelectorAll(\"#some-container p\");\n *\n * _.forEach(paragraphs, addClass(\"main\"));\n * // each \"p\" element in the container will have the \"main\" class now\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Undefined}\n */\n function forEach (arrayLike, iteratee) {\n for (var i = 0, len = _toArrayLength(arrayLike.length); i < len; i++) {\n iteratee(arrayLike[i], i, arrayLike);\n }\n }\n\n /**\n * Checks if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.contains|contains} for a curried version building a predicate.\n * @example\n * var numbers = [0, 1, 2, 3, NaN];\n *\n * _.isIn(numbers, 1) // => true\n * _.isIn(numbers, 0) // => true\n * _.isIn(numbers, -0) // => true\n * _.isIn(numbers, NaN) // => true\n * _.isIn(numbers, 5) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.contains|contains}\n * @since 0.13.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Boolean}\n */\n function isIn (arrayLike, value) {\n var result = false;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (areSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Generates an array with the values passed as arguments.
\n * Behaves like ES6's [Array.of]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of}.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.1.0\n * @param {...*} value\n * @returns {Array}\n */\n var list = _argsToArrayFrom(0);\n\n /**\n * Builds a new array by applying the iteratee function to each element of the\n * received array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.map([\"Joe\", \"Mario\", \"Jane\"], _.invoker(\"toUpperCase\")) // => [\"JOE\", \"MARIO\", \"JANE\"]\n *\n * _.map([4, 9, 16], Math.sqrt); // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.mapWith|mapWith}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function map (arrayLike, iteratee) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = iteratee(arrayLike[i], i, arrayLike);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.map|map} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var square = function (n) { return n * n; };\n * var getSquares = _.mapWith(square);\n *\n * getSquares([1, 2, 3, 4, 5]) // => [1, 4, 9, 16, 25]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.map|map}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ListIteratorCallback} iteratee\n * @returns {function}\n */\n var mapWith = _curry2(map, true);\n\n /**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new\n * value using the provided accumulator function.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.reduce([1, 2, 3, 4], _.sum) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRight|reduceRight}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduce = _makeReducer(1);\n\n /**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last\n * element instead.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduce|reduce}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduceRight = _makeReducer(-1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduceRight} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceRightWith(_.sum)(arr) // => 15\n * _.reduceRightWith(_.subtract)(arr) // => -5\n * _.reduceRightWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceWith|reduceWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceRightWith = _makePartial3(reduceRight, true);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduce} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceWith(_.sum)(arr) // => 15\n * _.reduceWith(_.subtract)(arr) // => -13\n * _.reduceWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRightWith|reduceRightWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceWith = _makePartial3(reduce, true);\n\n /**\n * Reverses a copy of the given array-like object.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.reverse(arr) // => [3, 2, 1];\n *\n * // `arr` still is [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.19.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function reverse (arrayLike) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0, ofs = len - 1; i < len; i++) {\n result[i] = arrayLike[ofs - i];\n }\n\n return result;\n }\n\n /**\n * Builds an array by extracting a portion of an array-like object.
\n * Note that unlike the native array method this function ensures that dense\n * arrays are returned.
\n * Also, unlike the native method, the start and end\n * parameters aren't optional and will be simply converted to integer.
\n * See {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.slice(arr, 0, 2) // => [1, 2]\n * _.slice(arr, 2, -1) // => [3, 4]\n * _.slice(arr, -3, 5) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sliceAt|sliceAt}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\n function slice (arrayLike, start, end) {\n var len = _toArrayLength(arrayLike.length);\n var begin = _toInteger(start);\n var upTo = _toInteger(end);\n\n if (begin < 0) {\n begin = begin < -len ? 0 : begin + len;\n }\n\n if (upTo < 0) {\n upTo = upTo < -len ? 0 : upTo + len;\n } else if (upTo > len) {\n upTo = len;\n }\n\n var resultLen = upTo - begin;\n var result = resultLen > 0 ? Array(resultLen) : [];\n\n for (var i = 0; i < resultLen; i++) {\n result[i] = arrayLike[begin + i];\n }\n\n return result;\n }\n\n /**\n * Given the start and end bounds, builds a partial application\n * of {@link module:lamb.slice|slice} expecting the array-like object to slice.
\n * See also {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var s = \"hello\";\n * var dropFirstAndLast = _.sliceAt(1, -1);\n *\n * dropFirstAndLast(arr) // => [2, 3, 4]\n * dropFirstAndLast(s) // => [\"e\", \"l\", \"l\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.slice|slice}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.48.0\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Function}\n */\n var sliceAt = _makePartial3(slice);\n\n /**\n * Checks if at least one element in an array-like object satisfies the given predicate.
\n * The function will stop calling the predicate as soon as it returns a truthy value.
\n * Note that unlike the native\n * [Array.prototype.some]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: false},\n * {\"name\": \"John\", \"age\": 40, active: false},\n * {\"name\": \"Mario\", \"age\": 17, active: false},\n * {\"name\": \"Paolo\", \"age\": 15, active: false}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.someIn(persons, isAdult) // => true\n * _.someIn(persons, isActive) // => false\n *\n * @example Showing the difference with Array.prototype.some:\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.some(_.isUndefined) // => false\n * _.someIn(arr, _.isUndefined) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.some|some}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var someIn = _makeArrayChecker(false);\n\n /**\n * A curried version of {@link module:lamb.someIn|someIn} that uses the given predicate to\n * build a function waiting for the array-like to act upon.\n * @example\n * var data = [1, 3, 5, 6, 7, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var containsEvens = _.some(isEven);\n * var containsStrings = _.some(_.isType(\"String\"));\n *\n * containsEvens(data) // => true\n * containsStrings(data) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.someIn|someIn}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var some = _curry2(someIn, true);\n\n lamb.contains = contains;\n lamb.every = every;\n lamb.everyIn = everyIn;\n lamb.filter = filter;\n lamb.filterWith = filterWith;\n lamb.find = find;\n lamb.findIndex = findIndex;\n lamb.findIndexWhere = findIndexWhere;\n lamb.findWhere = findWhere;\n lamb.forEach = forEach;\n lamb.isIn = isIn;\n lamb.list = list;\n lamb.map = map;\n lamb.mapWith = mapWith;\n lamb.reduce = reduce;\n lamb.reduceRight = reduceRight;\n lamb.reduceRightWith = reduceRightWith;\n lamb.reduceWith = reduceWith;\n lamb.reverse = reverse;\n lamb.slice = slice;\n lamb.sliceAt = sliceAt;\n lamb.some = some;\n lamb.someIn = someIn;\n\n /**\n * Accepts a series of functions and builds a function that applies the received\n * arguments to each one and returns the first non-undefined value.
\n * Meant to work in sinergy with {@link module:lamb.case|case} and\n * {@link module:lamb.invoker|invoker}, can be useful as a strategy pattern for functions,\n * to mimic conditional logic or pattern matching, and also to build polymorphic functions.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var filterString = _.compose(_.invoker(\"join\", \"\"), _.filter);\n * var filterAdapter = _.adapter(\n * _.invoker(\"filter\"),\n * _.case(_.isType(\"String\"), filterString)\n * );\n *\n * filterAdapter([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterAdapter(\"123456\", isEven) // => \"246\"\n * filterAdapter({}, isEven) // => undefined\n *\n * // obviously it's composable\n * var filterWithDefault = _.adapter(filterAdapter, _.always(\"Not implemented\"));\n *\n * filterWithDefault([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterWithDefault(\"123456\", isEven) // => \"246\"\n * filterWithDefault({}, isEven) // => \"Not implemented\"\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.case|case}\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.6.0\n * @param {...Function} fn\n * @returns {Function}\n */\n function adapter () {\n var functions = list.apply(null, arguments);\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = functions[i].apply(this, arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n }\n\n /**\n * Accepts a series of predicates and builds a new one that returns true if they are all satisfied\n * by the same arguments. The functions in the series will be applied one at a time until a\n * false value is produced, which is returned immediately.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositiveEven = _.allOf(isEven, _.isGT(0));\n *\n * isPositiveEven(-2) // => false\n * isPositiveEven(11) // => false\n * isPositiveEven(6) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.anyOf|anyOf}\n * @since 0.1.0\n * @param {...Function} predicate\n * @returns {Function}\n */\n function allOf () {\n var predicates = list.apply(null, arguments);\n\n return function () {\n for (var i = 0, len = predicates.length; i < len; i++) {\n if (!predicates[i].apply(this, arguments)) {\n return false;\n }\n }\n\n return true;\n };\n }\n\n /**\n * Accepts a series of predicates and builds a new one that returns true if at least one of them is\n * satisfied by the received arguments. The functions in the series will be applied one at a time\n * until a true value is produced, which is returned immediately.\n * @example\n * var users = [\n * {id: 1, name: \"John\", group: \"guest\"},\n * {id: 2, name: \"Jane\", group: \"root\"},\n * {id: 3, name: \"Mario\", group: \"admin\"}\n * ];\n * var isInGroup = _.partial(_.hasKeyValue, [\"group\"]);\n * var isSuperUser = _.anyOf(isInGroup(\"admin\"), isInGroup(\"root\"));\n *\n * isSuperUser(users[0]) // => false\n * isSuperUser(users[1]) // => true\n * isSuperUser(users[2]) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.allOf|allOf}\n * @since 0.1.0\n * @param {...Function} predicate\n * @returns {Function}\n */\n function anyOf () {\n var predicates = list.apply(null, arguments);\n\n return function () {\n for (var i = 0, len = predicates.length; i < len; i++) {\n if (predicates[i].apply(this, arguments)) {\n return true;\n }\n }\n\n return false;\n };\n }\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValue\" comparison.
\n * Note that this doesn't behave as the strict equality operator, but rather as a shim of ES6's\n * [Object.is]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is}.\n * Differences are that 0 and -0 aren't the same value and, finally,\n * NaN is equal to itself.
\n * See also {@link module:lamb.is|is} for a curried version building a predicate and\n * {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ} to perform a \"SameValueZero\"\n * comparison.\n * @example\n * var testObject = {};\n *\n * _.areSame({}, testObject) // => false\n * _.areSame(testObject, testObject) // => true\n * _.areSame(\"foo\", \"foo\") // => true\n * _.areSame(0, -0) // => false\n * _.areSame(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.is|is}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSame (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : areSVZ(a, b);\n }\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValueZero\" comparison.
\n * With this comparison NaN is equal to itself, but 0 and -0 are\n * considered the same value.
\n * See also {@link module:lamb.isSVZ|isSVZ} for a curried version building a predicate and\n * {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.areSVZ({}, testObject) // => false\n * _.areSVZ(testObject, testObject) // => true\n * _.areSVZ(\"foo\", \"foo\") // => true\n * _.areSVZ(0, -0) // => true\n * _.areSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.isSVZ|isSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSVZ (a, b) {\n return a !== a ? b !== b : a === b; // eslint-disable-line no-self-compare\n }\n\n /**\n * Builds a case for {@link module:lamb.adapter|adapter}.
\n * The function will apply the received arguments to fn if the predicate is satisfied\n * with the same arguments, otherwise will return undefined.
\n * See also {@link module:lamb.condition|condition} to build a condition with two branching functions.\n * @example\n * var halveIfNumber = _.case(_.isType(\"Number\"), _.divideBy(2));\n *\n * halveIfNumber(2) // => 1\n * halveIfNumber(\"2\") // => undefined\n *\n * @memberof module:lamb\n * @category Logic\n * @alias case\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.condition|condition}\n * @since 0.51.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function case_ (predicate, fn) {\n return function () {\n return predicate.apply(this, arguments) ? fn.apply(this, arguments) : void 0;\n };\n }\n\n /**\n * Builds a function that will apply the received arguments to trueFn,\n * if the predicate is satisfied with the same arguments, or to falseFn otherwise.
\n * Although you can use other conditions as trueFn or falseFn,\n * it's probably better to use {@link module:lamb.adapter|adapter} to build more complex behaviours.
\n * See also {@link module:lamb.unless|unless} and {@link module:lamb.when|when} as they are\n * shortcuts to common use cases.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveEvenAndDoubleOdd = _.condition(isEven, _.divideBy(2), _.multiplyBy(2));\n *\n * halveEvenAndDoubleOdd(5) // => 10\n * halveEvenAndDoubleOdd(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @since 0.2.0\n * @param {Function} predicate\n * @param {Function} trueFn\n * @param {Function} falseFn\n * @returns {Function}\n */\n function condition (predicate, trueFn, falseFn) {\n return function () {\n return (predicate.apply(this, arguments) ? trueFn : falseFn).apply(this, arguments);\n };\n }\n\n /**\n * Verifies that the first given value is greater than the second.
\n * Wraps the native > operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.gt(today, pastDate) // => true\n * _.gt(pastDate, today) // => false\n * _.gt(3, 4) // => false\n * _.gt(3, 3) // => false\n * _.gt(3, 2) // => true\n * _.gt(0, -0) // => false\n * _.gt(-0, 0) // => false\n * _.gt(\"a\", \"A\") // => true\n * _.gt(\"b\", \"a\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gt (a, b) {\n return a > b;\n }\n\n /**\n * Verifies that the first given value is greater than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * >= operator, so -0 === 0.\n * @example\n * _.gte(3, 4) // => false\n * _.gte(3, 3) // => true\n * _.gte(3, 2) // => true\n * _.gte(0, -0) // => true\n * _.gte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gt|gt}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gte (a, b) {\n return a >= b;\n }\n\n /**\n * A curried version of {@link module:lamb.areSame|areSame}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValue\"\n * comparison.
\n * See also {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ}\n * to perform a \"SameValueZero\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.is(john);\n * var isNegativeZero = _.is(-0);\n * var isReallyNaN = _.is(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isNegativeZero(0) // => false\n * isNegativeZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSame|areSame}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var is = _curry2(areSame);\n\n /**\n * A right curried version of {@link module:lamb.gt|gt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than the one received by the predicate.\n * @example\n * var isGreaterThan5 = _.isGT(5);\n *\n * isGreaterThan5(3) // => false\n * isGreaterThan5(5) // => false\n * isGreaterThan5(7) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGT = _curry2(gt, true);\n\n /**\n * A right curried version of {@link module:lamb.gte|gte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than or equal to the one received by the predicate.\n * @example\n * var isPositiveOrZero = _.isGTE(0);\n *\n * isPositiveOrZero(-3) // => false\n * isPositiveOrZero(-0) // => true\n * isPositiveOrZero(0) // => true\n * isPositiveOrZero(5) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGT|isGT}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGTE = _curry2(gte, true);\n\n /**\n * A right curried version of {@link module:lamb.lt|lt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than the one received by the predicate.\n * @example\n * var isLessThan5 = _.isLT(5);\n *\n * isLessThan5(7) // => false\n * isLessThan5(5) // => false\n * isLessThan5(3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLT = _curry2(lt, true);\n\n /**\n * A right curried version of {@link module:lamb.lte|lte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than or equal to the one received by the predicate.\n * @example\n * var isNegativeOrZero = _.isLTE(0);\n *\n * isNegativeOrZero(5) // => false\n * isNegativeOrZero(-0) // => true\n * isNegativeOrZero(0) // => true\n * isNegativeOrZero(-3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLT|isLT}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLTE = _curry2(lte, true);\n\n /**\n * A curried version of {@link module:lamb.areSVZ|areSVZ}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValueZero\"\n * comparison.
\n * See also {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is}\n * to perform a \"SameValue\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.isSVZ(john);\n * var isZero = _.isSVZ(0);\n * var isReallyNaN = _.isSVZ(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isZero(0) // => true\n * isZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSVZ|areSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var isSVZ = _curry2(areSVZ);\n\n /**\n * Verifies that the first given value is less than the second.
\n * Wraps the native < operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.lt(today, pastDate) // => false\n * _.lt(pastDate, today) // => true\n * _.lt(3, 4) // => true\n * _.lt(3, 3) // => false\n * _.lt(3, 2) // => false\n * _.lt(0, -0) // => false\n * _.lt(-0, 0) // => false\n * _.lt(\"a\", \"A\") // => false\n * _.lt(\"a\", \"b\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lt (a, b) {\n return a < b;\n }\n\n /**\n * Verifies that the first given value is less than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * <= operator, so -0 === 0.\n * @example\n * _.lte(3, 4) // => true\n * _.lte(3, 3) // => true\n * _.lte(3, 2) // => false\n * _.lte(0, -0) // => true\n * _.lte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lt|lt}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lte (a, b) {\n return a <= b;\n }\n\n /**\n * Returns a predicate that negates the given one.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isOdd = _.not(isEven);\n *\n * isOdd(5) // => true\n * isOdd(4) // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @since 0.1.0\n * @param {Function} predicate\n * @returns {Function}\n */\n function not (predicate) {\n return function () {\n return !predicate.apply(this, arguments);\n };\n }\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate isn't satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.when|when} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its trueFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveUnlessIsEven = _.unless(isEven, _.divideBy(2));\n *\n * halveUnlessIsEven(5) // => 2.5\n * halveUnlessIsEven(6) // => 6\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.when|when}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function unless (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? value : fn.call(this, value);\n };\n }\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate is satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.unless|unless} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its falseFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var halveIfEven = _.when(isEven, _.divideBy(2));\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function when (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? fn.call(this, value) : value;\n };\n }\n\n lamb.adapter = adapter;\n lamb.allOf = allOf;\n lamb.anyOf = anyOf;\n lamb.areSame = areSame;\n lamb.areSVZ = areSVZ;\n lamb.case = case_;\n lamb.condition = condition;\n lamb.gt = gt;\n lamb.gte = gte;\n lamb.is = is;\n lamb.isGT = isGT;\n lamb.isGTE = isGTE;\n lamb.isLT = isLT;\n lamb.isLTE = isLTE;\n lamb.isSVZ = isSVZ;\n lamb.lt = lt;\n lamb.lte = lte;\n lamb.not = not;\n lamb.unless = unless;\n lamb.when = when;\n\n /**\n * A curried version of {@link module:lamb.sum|sum}.\n * @example\n * var add5 = _.add(5);\n *\n * _.add5(4) // => 9\n * _.add5(-2) // => 3\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.sum|sum}\n * @since 0.1.0\n * @param {Number} a\n * @returns {Function}\n */\n var add = _curry2(sum, true);\n\n /**\n * \"Clamps\" a number within the given limits, both included.
\n * The function will convert to number all its parameters before starting any\n * evaluation, and will return NaN if min is greater\n * than max.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n * _.clamp(0, 0, 10) // => 0\n * _.clamp(10, 0, 10) // => 10\n * _.is(_.clamp(-0, 0, 10), -0) // => true\n * _.clamp(10, 20, 15) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.clampWithin|clampWithin}\n * @since 0.13.0\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function clamp (n, min, max) {\n n = +n;\n min = +min;\n max = +max;\n\n if (min > max) {\n return NaN;\n } else {\n return n < min ? min : n > max ? max : n;\n }\n }\n\n /**\n * A curried version of {@link module:lamb.clamp|clamp}, expecting a min\n * and a max value, that builds a function waiting for the number to clamp.\n * @example\n * _.clampWithin(0, 10)(-5) // => 0\n * _.clampWithin(0, 10)(5) // => 5\n * _.clampWithin(0, 10)(15) // => 10\n * _.clampWithin(0, 10)(0) // => 0\n * _.clampWithin(0, 10)(10) // => 10\n * _.is(_.clampWithin(0, 10)(-0), -0) // => true\n * _.clampWithin(20, 15)(10) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.clamp|clamp}\n * @since 0.47.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Function}\n */\n var clampWithin = _makePartial3(clamp);\n\n /**\n * A curried version of {@link module:lamb.subtract|subtract} that expects the\n * subtrahend to build a function waiting for the minuend.\n * @example\n * var deduct5 = _.deduct(5);\n *\n * deduct5(12) // => 7\n * deduct5(3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.subtract|subtract}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var deduct = _curry2(subtract, true);\n\n /**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.divideBy|divideBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function divide (a, b) {\n return a / b;\n }\n\n /**\n * A curried version of {@link module:lamb.divide|divide} that expects a divisor to\n * build a function waiting for the dividend.\n * @example\n * var halve = divideBy(2);\n *\n * halve(10) // => 5\n * halve(5) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.divide|divide}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var divideBy = _curry2(divide, true);\n\n /**\n * Generates a sequence of values of the desired length with the provided iteratee.\n * The values being iterated, and received by the iteratee, are the results generated so far.\n * @example\n * var fibonacci = function (n, idx, results) {\n * return n + (results[idx - 1] || 0);\n * };\n *\n * _.generate(1, 10, fibonacci) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.range|range}\n * @since 0.21.0\n * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function generate (start, len, iteratee) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee(result[i], i, result));\n }\n\n return result;\n }\n\n /**\n * Verifies whether the received value is a finite number.
\n * Behaves almost as a shim of ES6's [Number.isFinite]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isFinite(5) // => true\n * _.isFinite(new Number(5)) // => true\n * _.isFinite(Infinity) // => false\n * _.isFinite(-Infinity) // => false\n * _.isFinite(\"5\") // => false\n * _.isFinite(NaN) // => false\n * _.isFinite(null) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @alias isFinite\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isFinite_ (value) {\n return type(value) === \"Number\" && isFinite(value);\n }\n\n /**\n * Verifies whether the received value is a number and an integer.\n * Behaves almost as a shim of ES6's [Number.isInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isInteger(5) // => true\n * _.isInteger(new Number(5)) // => true\n * _.isInteger(2.5) // => false\n * _.isInteger(Infinity) // => false\n * _.isInteger(-Infinity) // => false\n * _.isInteger(\"5\") // => false\n * _.isInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isSafeInteger|isSafeInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isInteger (value) {\n return type(value) === \"Number\" && value % 1 === 0;\n }\n\n /**\n * Verifies whether the received value is a \"safe integer\", meaning that is a number and that\n * can be exactly represented as an IEEE-754 double precision number.\n * The safe integers consist of all integers from -(253 - 1) inclusive to\n * 253 - 1 inclusive.
\n * Behaves almost as a shim of ES6's [Number.isSafeInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isSafeInteger(5) // => true\n * _.isSafeInteger(new Number(5)) // => true\n * _.isSafeInteger(Math.pow(2, 53) - 1) // => true\n * _.isSafeInteger(Math.pow(2, 53)) // => false\n * _.isSafeInteger(2e32) // => false\n * _.isSafeInteger(2.5) // => false\n * _.isSafeInteger(Infinity) // => false\n * _.isSafeInteger(-Infinity) // => false\n * _.isSafeInteger(\"5\") // => false\n * _.isSafeInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isInteger|isInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isSafeInteger (value) {\n return isInteger(value) && Math.abs(value) <= 9007199254740991;\n }\n\n /**\n * Performs the modulo operation and should not be confused with the\n * {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not\n * a truncated one, hence the sign of the dividend is not kept, unlike the\n * {@link module:lamb.remainder|remainder}.\n * @example\n * _.modulo(5, 3) // => 2\n * _.remainder(5, 3) // => 2\n *\n * _.modulo(-5, 3) // => 1\n * _.remainder(-5, 3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.remainder|remainder}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function modulo (a, b) {\n return a - (b * Math.floor(a / b));\n }\n\n /**\n * Multiplies two numbers.\n * @example\n * _.multiply(5, 3) // => 15\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.multiplyBy|multiplyBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function multiply (a, b) {\n return a * b;\n }\n\n /**\n * A curried version of {@link module:lamb.multiply|multiply}.\n * @example\n * var double = _.multiplyBy(2);\n *\n * double(5) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.multiply|multiply}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var multiplyBy = _curry2(multiply, true);\n\n /**\n * Generates a random integer between two given integers, both included.\n * Note that no safety measure is taken if the provided arguments aren't integers, so\n * you may end up with unexpected (not really) results.\n * For example randomInt(0.1, 1.2) could be 2.\n * @example\n *\n * _.randomInt(1, 10) // => an integer >=1 && <= 10\n *\n * @memberof module:lamb\n * @category Math\n * @since 0.1.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function randomInt (min, max) {\n return Math.floor(Math.random() * (max - min + 1) + min);\n }\n\n /**\n * Generates an arithmetic progression of numbers starting from start up to,\n * but not including, limit, using the given step.\n * @example\n * _.range(2, 10) // => [2, 3, 4, 5, 6, 7, 8, 9]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(0, 3, 1) // => [0, 1, 2]\n * _.range(-0, 3, 1) // => [-0, 1, 2]\n * _.range(1, -10, 2) // => []\n * _.range(3, 5, -1) // => []\n *\n * @example Behaviour if step happens to be zero:\n * _.range(2, 10, 0) // => [2]\n * _.range(2, -10, 0) // => [2]\n * _.range(2, 2, 0) // => []\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.generate|generate}\n * @since 0.1.0\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\n function range (start, limit, step) {\n start = _forceToNumber(start);\n limit = _forceToNumber(limit);\n step = arguments.length === 3 ? _forceToNumber(step) : 1;\n\n if (step === 0) {\n return limit === start ? [] : [start];\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n var result = Array(len);\n\n for (var i = 0, last = start; i < len; i++) {\n result[i] = last;\n last += step;\n }\n\n return result;\n }\n\n /**\n * Gets the remainder of the division of two numbers.\n * Not to be confused with the {@link module:lamb.modulo|modulo} as the remainder\n * keeps the sign of the dividend and may lead to some unexpected results.\n * @example\n * // example of wrong usage of the remainder\n * // (in this case the modulo operation should be used)\n * var isOdd = function (n) { return _.remainder(n, 2) === 1; };\n * isOdd(-3) // => false as -3 % 2 === -1\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.modulo|modulo}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function remainder (a, b) {\n return a % b;\n }\n\n /**\n * Subtracts two numbers.\n * @example\n * _.subtract(5, 3) // => 2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.deduct|deduct}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function subtract (a, b) {\n return a - b;\n }\n\n /**\n * Sums two numbers.\n * @example\n * _.sum(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.add|add}\n * @since 0.50.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function sum (a, b) {\n return a + b;\n }\n\n lamb.add = add;\n lamb.clamp = clamp;\n lamb.clampWithin = clampWithin;\n lamb.deduct = deduct;\n lamb.divide = divide;\n lamb.divideBy = divideBy;\n lamb.generate = generate;\n lamb.isFinite = isFinite_;\n lamb.isInteger = isInteger;\n lamb.isSafeInteger = isSafeInteger;\n lamb.modulo = modulo;\n lamb.multiply = multiply;\n lamb.multiplyBy = multiplyBy;\n lamb.randomInt = randomInt;\n lamb.range = range;\n lamb.remainder = remainder;\n lamb.subtract = subtract;\n lamb.sum = sum;\n\n /**\n * Accepts a constructor and builds a predicate expecting an object,\n * which will be tested to verify whether the prototype of the constructor\n * is in its prototype chain.
\n * Wraps in a convenient way the native\n * [instanceof]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof} operator.\n * @example\n * function SomeObjA () {}\n *\n * var a = new SomeObjA();\n * var sObj = new String(\"foo\");\n * var s = \"foo\";\n *\n * _.isInstanceOf(Object)(a) // => true\n * _.isInstanceOf(SomeObjA)(a) // => true\n *\n * _.isInstanceOf(Object)(sObj) // => true\n * _.isInstanceOf(String)(sObj) // => true\n *\n * _.isInstanceOf(Object)(s) // => false\n * _.isInstanceOf(String)(s) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.47.0\n * @param {*} constructor\n * @returns {Function}\n */\n function isInstanceOf (constructor) {\n return function (obj) {\n return obj instanceof constructor;\n };\n }\n\n /**\n * Verifies if a value is null or undefined.\n * @example\n * _.isNil(NaN) // => false\n * _.isNil({}) // => false\n * _.isNil(null) // => true\n * _.isNil(void 0) // => true\n * _.isNil() // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNull|isNull}\n * @see {@link module:lamb.isUndefined|isUndefined}\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNil (value) {\n return isNull(value) || isUndefined(value);\n }\n\n /**\n * Verifies if a value is null.\n * @example\n * _.isNull(null) // => true\n * _.isNull(void 0) // => false\n * _.isNull(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for undefined too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNull (value) {\n return value === null;\n }\n\n /**\n * Builds a predicate that expects a value to check against the specified type.\n * @example\n * var isString = _.isType(\"String\");\n *\n * isString(\"Hello\") // => true\n * isString(new String(\"Hi\")) // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.type|type}\n * @since 0.1.0\n * @param {String} typeName\n * @returns {Function}\n */\n function isType (typeName) {\n return function (value) {\n return type(value) === typeName;\n };\n }\n\n /**\n * Verifies if a value is undefined.\n * @example\n * _.isUndefined(null) // => false\n * _.isUndefined(void 0) // => true\n * _.isUndefined(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for null too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isUndefined (value) {\n return value === void 0;\n }\n\n /**\n * Retrieves the \"type tag\" from the given value.\n * @example\n * var x = 5;\n * var y = new Number(5);\n *\n * typeof x // => \"number\"\n * typeof y // => \"object\"\n * _.type(x) // => \"Number\"\n * _.type(y) // => \"Number\"\n *\n * _.type(Object.prototype.toString) // => \"Function\"\n * _.type(/a/) // => \"RegExp\"\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.9.0\n * @param {*} value\n * @returns {String}\n */\n function type (value) {\n return _objectProto.toString.call(value).slice(8, -1);\n }\n\n lamb.isInstanceOf = isInstanceOf;\n lamb.isNil = isNil;\n lamb.isNull = isNull;\n lamb.isType = isType;\n lamb.isUndefined = isUndefined;\n lamb.type = type;\n\n /**\n * A curried version of {@link module:lamb.getIndex|getIndex} that uses the provided index\n * to build a function expecting the array-like object holding the element we want to retrieve.\n * @example\n * var getFifthElement = _.getAt(4);\n *\n * getFifthElement([1, 2, 3, 4, 5]) // => 5\n * getFifthElement(\"foo bar\") // => \"b\"\n * getFifthElement([]) // => undefined\n * getFifthElement(\"foo\") // => undefined\n *\n * @example Using negative indexes:\n * _.getAt(-2)([1, 2, 3]) // => 2\n * _.getAt(-3)(\"foo\") // => \"f\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.16.0\n * @see {@link module:lamb.getIndex|getIndex}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @param {Number} index\n * @returns {Function}\n */\n var getAt = _curry2(getIndex, true);\n\n /**\n * Returns the value of the object property with the given key.\n * @example\n * var user = {name: \"John\"};\n *\n * _.getIn(user, \"name\") // => \"John\";\n * _.getIn(user, \"surname\") // => undefined\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getKey|getKey}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.18.0\n * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\n function getIn (obj, key) {\n return obj[key];\n }\n\n /**\n * Retrieves the element at the given index in an array-like object.
\n * Like {@link module:lamb.slice|slice} the index can be negative.
\n * If the index isn't supplied, or if its value isn't an integer within the array-like bounds,\n * the function will return undefined.
\n * getIndex will throw an exception when receives null or\n * undefined in place of an array-like object, but returns undefined\n * for any other value.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.getIndex(arr, 1) // => 2\n * _.getIndex(arr, -1) // => 5\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.getAt|getAt}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @returns {*}\n */\n function getIndex (arrayLike, index) {\n var idx = _toNaturalIndex(index, _toArrayLength(arrayLike.length));\n\n return idx === idx ? arrayLike[idx] : void 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * A curried version of {@link module:lamb.getIn|getIn}.
\n * Receives a property name and builds a function expecting the object from which we want to retrieve\n * the property.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {name: \"jane\"};\n * var getName = _.getKey(\"name\");\n *\n * getName(user1) // => \"john\"\n * getName(user2) // => \"jane\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var getKey = _curry2(getIn, true);\n\n /**\n * Builds a partial application of {@link module:lamb.getPathIn|getPathIn} with the given\n * path and separator, expecting the object to act upon.
\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * var getPwd = _.getPath(\"login.password\");\n * var getUsername = _.getPath(\"login/user.name\", \"/\");\n *\n * getPwd(user) // => \"abc123\";\n * getUsername(user) // => \"jdoe\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var getPath = _makePartial3(getPathIn);\n\n /**\n * Gets a nested property value from an object using the given path.
\n * The path is a string with property names separated by dots by default, but\n * it can be customised with the optional third parameter.
\n * You can use integers in the path, even negative ones, to refer to array-like\n * object indexes, but the priority will be given to existing object keys:\n * the last example explains this particular case.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * },\n * scores: [\n * {id: 1, value: 10},\n * {id: 2, value: 20},\n * {id: 3, value: 30}\n * ]\n * };\n *\n * _.getPathIn(user, \"name\") // => \"John\"\n * _.getPathIn(user, \"login.password\") // => \"abc123\";\n * _.getPathIn(user, \"login/user.name\", \"/\") // => \"jdoe\"\n * _.getPathIn(user, \"name.foo\") // => undefined\n * _.getPathIn(user, \"name.foo.bar\") // => undefined\n *\n * @example Accessing array-like objects indexes:\n * _.getPathIn(user, \"login.password.1\") // => \"b\"\n * _.getPathIn(user, \"scores.0\") // => {id: 1, value: 10}\n * _.getPathIn(user, \"scores.-1.value\") // => 30\n *\n * @example Priority will be given to existing object keys over indexes:\n * _.getPathIn(user, \"scores.-1\") // => {id: 3, value: 30}\n *\n * // let's do something funny\n * user.scores[\"-1\"] = \"foo bar\";\n *\n * _.getPathIn(user, \"scores.-1\") // => \"foo bar\";\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getPath|getPath}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\n function getPathIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).target;\n }\n\n /**\n * Retrieves the first element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.head([1, 2, 3]) // => 1\n * _.head(\"hello\") // => \"h\"\n * _.head([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.last|last}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var head = getAt(0);\n\n /**\n * Retrieves the last element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.last([1, 2, 3]) // => 3\n * _.last(\"hello\") // => \"o\"\n * _.last([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.head|head}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var last = getAt(-1);\n\n /**\n * A curried version of {@link module:lamb.setIndex|setIndex} that builds\n * a function that creates a copy of an array-like object with the given\n * index changed to the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.setAt(2, 99)(arr) // => [1, 2, 99, 4, 5]\n * arr // => [1, 2, 3, 4, 5]\n *\n * _.setAt(10, 99)(arr) // => [1, 2, 3, 4, 5] (not a reference to `arr`)\n *\n * @example Using negative indexes:\n * _.setAt(-1, 99)(arr) // => [1, 2, 3, 4, 99]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setIndex|setIndex}\n * @since 0.17.0\n * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\n var setAt = _makePartial3(_setIndex);\n\n /**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the remaining enumerable keys of the source object will be simply copied in the\n * result object without breaking references.
\n * If the specified key is not part of the source object, it will be added to the\n * result.
\n * The main purpose of the function is to work on simple plain objects used as\n * data structures, such as JSON objects, and makes no effort to play nice with\n * objects created from an OOP perspective (it's not worth it).
\n * For example the prototype of the result will be Object's regardless\n * of the source's one.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n *\n * _.setIn(user, \"name\", \"Jane\") // => {name: \"Jane\", surname: \"Doe\", age: 30}\n * _.setIn(user, \"gender\", \"male\") // => {name: \"John\", surname: \"Doe\", age: 30, gender: \"male\"}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setKey|setKey}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function setIn (source, key, value) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setIn(source, key, value);\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed to\n * the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.setIndex(arr, 1, 99) // => [1, 99, 3]\n * _.setIndex(arr, -1, 99) // => [1, 2, 99]\n * _.setIndex(arr, 10, 99) // => [1, 2, 3] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setAt|setAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} value\n * @returns {Array}\n */\n var setIndex = aritize(_setIndex, 3);\n\n /**\n * Builds a partial application of {@link module:lamb.setIn|setIn} with the provided\n * key and value.
\n * The resulting function expects the object to act upon.
\n * Please refer to {@link module:lamb.setIn|setIn}'s description for explanations about\n * how the copy of the source object is made.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n * var setAgeTo40 = _.setKey(\"age\", 40);\n *\n * setAgeTo40(user) // => {name: \"john\", surname: \"doe\", age: 40}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n var setKey = _makePartial3(setIn);\n\n /**\n * Builds a partial application of {@link module:lamb.setPathIn|setPathIn} expecting the\n * object to act upon.
\n * See {@link module:lamb.setPathIn|setPathIn} for more details and examples.\n * @example\n * var user = {id: 1, status: {active: false}};\n * var activate = _.setPath(\"status.active\", true);\n *\n * activate(user) // => {id: 1, status: {active: true}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPathIn|setPathIn}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function setPath (path, value, separator) {\n return function (source) {\n return setPathIn(source, path, value, separator);\n };\n }\n\n /**\n * Allows to change a nested value in a copy of the provided object.
\n * The function will delegate the \"set action\" to {@link module:lamb.setIn|setIn} or\n * {@link module:lamb.setAt|setAt} depending on the value encountered in the path,\n * so please refer to the documentation of those functions for specifics about the\n * implementation.
\n * Note anyway that the distinction will be between Arrays, delegated\n * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects),\n * which will be delegated to {@link module:lamb.setIn|setIn}.
\n * As a result of that, array-like objects will be converted to objects having numbers as keys\n * and paths targeting non-object values will be converted to empty objects.
\n * You can anyway target array elements using integers in the path, even negative ones, but\n * the priority will be given to existing, and enumerable, object keys.
\n * Non-enumerable properties encountered in the path will be considered as non-existent properties.
\n * Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can\n * use custom path separators.\n * @example\n * var user = {id: 1, status: {active : false, scores: [2, 4, 6]}};\n *\n * _.setPathIn(user, \"status.active\", true) // => {id: 1, status: {active : true, scores: [2, 4, 6]}}\n *\n * @example Targeting arrays:\n * _.setPathIn(user, \"status.scores.0\", 8) // => {id: 1, status: {active : false, scores: [8, 4, 6]}}\n *\n * // you can use negative indexes as well\n * _.setPathIn(user, \"status.scores.-1\", 8) // => {id: 1, status: {active : false, scores: [2, 4, 8]}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.setPathIn(user, \"scores.0.value\", 8);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 8, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPath|setPath}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function setPathIn (source, path, value, separator) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setPathIn(source, _toPathParts(path, separator), value);\n }\n\n /**\n * Builds a function that creates a copy of an array-like object with the given index\n * changed by applying the provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateAt(1, toUpperCase)(arr) // => [\"a\", \"B\", \"c\"]\n * _.updateAt(-1, toUpperCase)(arr) // => [\"a\", \"b\", \"C\"]\n * _.updateAt(10, toUpperCase)(arr) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.updateIndex|updateIndex}\n * @since 0.22.0\n * @param {Number} index\n * @param {Function} updater\n * @returns {Function}\n */\n function updateAt (index, updater) {\n return function (arrayLike) {\n return _setIndex(arrayLike, index, null, updater);\n };\n }\n\n /**\n * Creates a copy of the given object having the desired key value updated by applying\n * the provided function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIn(user, \"name\", toUpperCase) // => {name: \"JOHN\", visits: 2}\n * _.updateIn(user, \"surname\", toUpperCase) // => {name: \"John\", visits: 2}\n *\n * @example Non-enumerable properties will be treated as non-existent:\n * var user = Object.create({name: \"John\"}, {visits: {value: 2}});\n *\n * _.updateIn(user, \"visits\", _.add(1)) // => {name: \"John\", visits: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateKey|updateKey}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {Object} source\n * @param {String} key\n * @param {Function} updater\n * @returns {Object}\n */\n function updateIn (source, key, updater) {\n return _isEnumerable(source, key) ?\n _setIn(source, key, updater(source[key])) :\n _merge(enumerables, source);\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed by applying the\n * provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIndex(arr, 1, toUpperCase) // => [\"a\", \"B\", \"c\"]\n * _.updateIndex(arr, -1, toUpperCase) // => [\"a\", \"b\", \"C\"]\n * _.updateIndex(arr, 10, toUpperCase) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.updateAt|updateAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {Function} updater\n * @returns {Array}\n */\n var updateIndex = partial(_setIndex, [_, _, null, _]);\n\n /**\n * Builds a partial application of {@link module:lamb.updateIn|updateIn} with the provided\n * key and updater, expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var incrementVisits = _.updateKey(\"visits\", _.add(1));\n *\n * incrementVisits(user) // => {name: \"John\", visits: 3}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.updateIn|updateIn}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {String} key\n * @param {Function} updater\n * @returns {Function}\n */\n var updateKey = _makePartial3(updateIn);\n\n /**\n * Builds a partial application of {@link module:lamb.updatePathIn|updatePathIn}\n * expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var incrementScores = _.updatePath(\"status.scores\", _.mapWith(_.add(1)))\n *\n * incrementScores(user) // => {id: 1, status: {scores: [3, 5, 7], visits: 0}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePathIn|updatePathIn}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function updatePath (path, updater, separator) {\n return function (source) {\n return updatePathIn(source, path, updater, separator);\n };\n }\n\n /**\n * Allows to change a nested value in a copy of the given object by applying the provided\n * function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var inc = _.add(1);\n *\n * _.updatePathIn(user, \"status.visits\", inc) // => {id: 1, status: {scores: [2, 4, 6]}, visits: 1}\n *\n * @example Targeting arrays:\n * _.updatePathIn(user, \"status.scores.0\", inc) // => {id: 1, status: {scores: [3, 4, 6], visits: 0}}\n *\n * // you can use negative indexes as well\n * _.updatePathIn(user, \"status.scores.-1\", inc) // => {id: 1, status: {scores: [2, 4, 7], visits: 0}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.updatePathIn(user, \"scores.0.value\", inc);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 3, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePath|updatePath}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function updatePathIn (source, path, updater, separator) {\n var parts = _toPathParts(path, separator);\n var pathInfo = _getPathInfo(source, parts, false);\n\n if (pathInfo.isValid) {\n return _setPathIn(source, parts, updater(pathInfo.target));\n } else {\n return Array.isArray(source) ? slice(source, 0, source.length) : _merge(enumerables, source);\n }\n }\n\n lamb.getAt = getAt;\n lamb.getIn = getIn;\n lamb.getIndex = getIndex;\n lamb.getKey = getKey;\n lamb.getPath = getPath;\n lamb.getPathIn = getPathIn;\n lamb.head = head;\n lamb.last = last;\n lamb.setAt = setAt;\n lamb.setIn = setIn;\n lamb.setIndex = setIndex;\n lamb.setKey = setKey;\n lamb.setPath = setPath;\n lamb.setPathIn = setPathIn;\n lamb.updateAt = updateAt;\n lamb.updateIn = updateIn;\n lamb.updateIndex = updateIndex;\n lamb.updateKey = updateKey;\n lamb.updatePath = updatePath;\n lamb.updatePathIn = updatePathIn;\n\n /**\n * A curried version of {@link module:lamb.appendTo|appendTo} that uses the value to append\n * to build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.append(5)(arr) // => [1, 2, 3, 4, 5]\n * _.append([5])(arr) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.appendTo|appendTo}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {*} value\n * @returns {Function}\n */\n var append = _curry2(appendTo, true);\n\n /**\n * Appends the given value at the end of a copy of the provided array-like object.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.appendTo(arr, 5) // => [1, 2, 3, 4, 5]\n * _.appendTo(arr, [5]) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.append|append}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Array}\n */\n function appendTo (arrayLike, value) {\n return slice(arrayLike, 0, arrayLike.length).concat([value]);\n }\n\n /**\n * Returns an array of unique items present only in the first of the two given\n * array-like objects. To determine uniqueness the function uses the\n * [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 1, 3, 4];\n * var a2 = [2, 4, 5, 6];\n * var a3 = [3, 4, 5, 2, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a2, a3) // => [6]\n * _.difference(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.intersection|intersection}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @since 0.6.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} other\n * @returns {Array}\n */\n function difference (arrayLike, other) {\n var isNotInOther = partial(not(isIn), [other]);\n\n return uniques(filter(arrayLike, isNotInOther));\n }\n\n /**\n * A curried version of {@link module:lamb.dropFrom|dropFrom} that expects the number of elements\n * to drop to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.dropFrom|dropFrom} about passing a\n * negative n.\n * @example\n * var drop2 = _.drop(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.5.0\n * @see {@link module:lamb.dropFrom|dropFrom}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var drop = _curry2(dropFrom, true);\n\n /**\n * Builds an array without the first n elements of the given array or array-like object.\n * Note that, being this only a shortcut for a specific use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.dropFrom(arr, 2) // => [3, 4, 5]\n * _.dropFrom(arr, -1) // => [5]\n * _.dropFrom(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function dropFrom (arrayLike, n) {\n return slice(arrayLike, n, arrayLike.length);\n }\n\n /**\n * Builds a function that drops the first n elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropWhileIsEven = _.dropWhile(isEven);\n *\n * dropWhileIsEven([2, 4, 6, 8]) // => []\n * dropWhileIsEven([2, 4, 7, 8]) // => [7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.takeWhile|takeWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n function dropWhile (predicate) {\n return function (arrayLike) {\n return slice(arrayLike, _getNumConsecutiveHits(arrayLike, predicate), arrayLike.length);\n };\n }\n\n /**\n * Similar to {@link module:lamb.map|map}, but if the mapping function returns an array this will\n * be concatenated, rather than pushed, to the final result.\n * @example Showing the difference with map:\n * var words = [\"foo\", \"bar\"];\n * var toCharArray = function (s) { return s.split(\"\"); };\n *\n * _.map(words, toCharArray) // => [[\"f\", \"o\", \"o\"], [\"b\", \"a\", \"r\"]]\n * _.flatMap(words, toCharArray) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.flatMapWith|flatMapWith}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.1.0\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function flatMap (array, iteratee) {\n return reduce(array, function (result, el, idx, arr) {\n var v = iteratee(el, idx, arr);\n\n if (!Array.isArray(v)) {\n v = [v];\n }\n\n for (var i = 0, len = v.length, rLen = result.length; i < len; i++) {\n result[rLen + i] = v[i];\n }\n\n return result;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.flatMap|flatMap} that uses provided iteratee\n * to build a function expecting the array to act upon.\n * @example\n * var toCharArray = function (s) { return s.split(\"\"); };\n * var wordsToCharArray = _.flatMapWith(toCharArray);\n *\n * wordsToCharArray([\"foo\", \"bar\"]) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatMap|flatMap}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.11.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var flatMapWith = _curry2(flatMap, true);\n\n /**\n * Flattens an array.\n * @example Showing the difference with shallowFlatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.shallowFlatten|shallowFlatten}\n * @since 0.1.0\n * @param {Array} array\n * @returns {Array}\n */\n var flatten = _makeArrayFlattener(true);\n\n /**\n * Returns a copy of the given array-like object without the last element.\n * @example\n * _.init([1, 2, 3, 4]) // => [1, 2, 3]\n * _.init([1]) // => []\n * _.init([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.tail|tail}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var init = partial(slice, [_, 0, -1]);\n\n /**\n * Inserts the provided element in a copy of an array-like object at the\n * specified index.
\n * If the index is greater than the length of the array-like, the element\n * will be appended at the end.
\n * Negative indexes are allowed; when a negative index is out of bounds\n * the element will be inserted at the start of the resulting array.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insert(arr, 3, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, -2, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, 10, 99) // => [1, 2, 3, 4, 5, 99]\n * _.insert(arr, -10, 99) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.insertAt|insertAt}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} element\n * @returns {Array}\n */\n function insert (arrayLike, index, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n result.splice(index, 0, element);\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.insert|insert}\n * expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insertAt(3, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(-2, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(10, 99)(arr) // => [1, 2, 3, 4, 5, 99]\n * _.insertAt(-10, 99)(arr) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.insert|insert}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.27.0\n * @param {Number} index\n * @param {*} element\n * @returns {Function}\n */\n var insertAt = _makePartial3(insert);\n\n /**\n * Returns an array of every unique item that is included in all given arrays or array-like objects.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 2, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a2, a3) // => [5, 6]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @since 0.5.0\n * @param {...ArrayLike} arrayLike\n * @returns {Array}\n */\n function intersection () {\n if (arguments.length === 0) {\n return [];\n }\n\n var rest = _argsTail.apply(null, arguments);\n\n return filter(uniques(arguments[0]), function (item) {\n return everyIn(rest, contains(item));\n });\n }\n\n /**\n * Splits an array-like object in two lists: the first with the elements satisfying the given predicate,\n * the others with the remaining elements.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * _.partition(numbers, isEven) // => [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.partitionWith|partitionWith}\n * @since 0.11.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Array}\n */\n function partition (arrayLike, predicate) {\n var result = [[], []];\n var len = arrayLike.length;\n\n for (var i = 0, el; i < len; i++) {\n el = arrayLike[i];\n result[predicate(el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.partition|partition} that uses the provided\n * predicate to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * ];\n * var isActive = _.hasKeyValue(\"active\", true);\n * var splitByActiveStatus = _.partitionWith(isActive);\n *\n * splitByActiveStatus(users) // =>\n * // [[\n * // {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true}\n * // ], [\n * // {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * // {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * // ]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.partition|partition}\n * @since 0.11.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var partitionWith = _curry2(partition, true);\n\n /**\n * \"Plucks\" the values of the specified key from a list of objects.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n *\n * _.pluck(persons, \"age\") // => [12, 40, 18, 15]\n *\n * var lists = [\n * [1, 2],\n * [3, 4, 5],\n * [6]\n * ];\n *\n * _.pluck(lists, \"length\") // => [2, 3, 1]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pluckKey|pluckKey}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {String} key\n * @returns {Array}\n */\n function pluck (arrayLike, key) {\n return map(arrayLike, getKey(key));\n }\n\n /**\n * A curried version of {@link module:lamb.pluck|pluck} expecting the key to retrieve to\n * build a function waiting for the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n * var getAges = _.pluckKey(\"age\");\n *\n * getAges(persons) // => [12, 40, 18, 15]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pluck|pluck}\n * @since 0.12.0\n * @param {String} key\n * @returns {Function}\n */\n var pluckKey = compose(mapWith, getKey);\n\n /**\n * A curried version of {@link module:lamb.pullFrom|pullFrom} expecting\n * a list of values to build a function waiting for an array-like object.
\n * The new function will create an array copy of the array-like without\n * the specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var scores = [40, 20, 30, 10];\n * var newScores = [30, 10];\n * var pullNewScores = _.pull(newScores);\n *\n * pullNewScores(scores) // => [40, 20]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pullFrom|pullFrom}\n * @since 0.45.0\n * @param {ArrayLike} values\n * @returns {Function}\n */\n var pull = _curry2(pullFrom, true);\n\n /**\n * Creates an array copy of the given array-like object without the\n * specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.pullFrom(arr, [2, 5]) // => [1, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pull|pull}\n * @since 0.45.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} values\n * @returns {Array}\n */\n function pullFrom (arrayLike, values) {\n return values ? filter(arrayLike, function (element) {\n return !isIn(values, element);\n }) : slice(arrayLike, 0, arrayLike.length);\n }\n\n /**\n * Flattens the \"first level\" of an array.\n * @example Showing the difference with flatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatten|flatten}\n * @since 0.9.0\n * @param {Array} array\n * @returns {Array}\n */\n var shallowFlatten = _makeArrayFlattener(false);\n\n /**\n * Returns a copy of the given array-like object without the first element.\n * @example\n * _.tail([1, 2, 3, 4]) // => [2, 3, 4]\n * _.tail([1]) // => []\n * _.tail([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.init|init}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var tail = drop(1);\n\n /**\n * A curried version of {@link module:lamb.takeFrom|takeFrom} that expects the number of elements\n * to retrieve to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.takeFrom|takeFrom} about passing a\n * negative n.\n * @example\n * var take2 = _.take(2);\n *\n * take2([1, 2, 3, 4, 5]) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeFrom|takeFrom}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.5.0\n * @param {Number} n\n * @returns {Function}\n */\n var take = _curry2(takeFrom, true);\n\n /**\n * Retrieves the first n elements from an array or array-like object.
\n * Note that, being this a shortcut for a common use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.takeFrom(arr, 3) // => [1, 2, 3]\n * _.takeFrom(arr, -1) // => [1, 2, 3, 4]\n * _.takeFrom(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function takeFrom (arrayLike, n) {\n return slice(arrayLike, 0, n);\n }\n\n /**\n * Builds a function that takes the first n elements satisfying a predicate from\n * an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeWhileIsEven = _.takeWhile(isEven);\n *\n * takeWhileIsEven([1, 2, 4, 6, 8]) // => []\n * takeWhileIsEven([2, 4, 7, 8]) // => [2, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n function takeWhile (predicate) {\n return function (arrayLike) {\n return slice(arrayLike, 0, _getNumConsecutiveHits(arrayLike, predicate));\n };\n }\n\n /**\n * Transposes a matrix. Can also be used to reverse a {@link module:lamb.zip|zip} operation.
\n * Just like {@link module:lamb.zip|zip}, the received array-like objects will be truncated to the\n * shortest length.\n * @example Transposing a matrix:\n * _.transpose([\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ]) // =>\n * // [\n * // [1, 4, 7],\n * // [2, 5, 8],\n * // [3, 6, 9]\n * // ]\n *\n * @example Showing the relationship with zip:\n * var zipped = _.zip([\"a\", \"b\", \"c\"], [1, 2, 3]); // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.transpose(zipped) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function transpose (arrayLike) {\n var minLen = MAX_ARRAY_LENGTH;\n var len = _toArrayLength(arrayLike.length);\n\n if (len === 0) {\n return [];\n }\n\n for (var j = 0, elementLen; j < len; j++) {\n elementLen = _toArrayLength(arrayLike[j].length);\n\n if (elementLen < minLen) {\n minLen = elementLen;\n }\n }\n\n var result = Array(minLen);\n\n for (var i = 0, el; i < minLen; i++) {\n el = result[i] = Array(len);\n\n for (j = 0; j < len; j++) {\n el[j] = arrayLike[j][i];\n }\n }\n\n return result;\n }\n\n /**\n * Returns a list of every unique element present in the given array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.unionBy|unionBy} if you need to transform the values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.union([1, 2, 3, 2], [3, 4], [1, 5]) // => [1, 2, 3, 4, 5]\n * _.union(\"abc\", \"bcd\", \"cde\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.5.0\n * @param {...ArrayLike} arrayLike\n * @returns {Array}\n */\n var union = unionBy(identity);\n\n /**\n * Using the provided iteratee, builds a function that will return an array of the unique elements\n * in the provided array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.union|union} if you don't need to transform the values.\n * @example\n * var unionByFloor = _.unionBy(Math.floor);\n *\n * unionByFloor([2.8, 3.2, 1.5], [3.5, 1.2, 4]) // => [2.8, 3.2, 1.5, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.union|union}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function unionBy (iteratee) {\n return compose(uniquesBy(iteratee), flatMapWith(drop(0)), list);\n }\n\n /**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniquesBy|uniquesBy} if you need to transform your values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.uniques([-0, 1, 2, 0, 2, 3, 4, 3, 5, 1]) // => [-0, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.uniquesBy|uniquesBy}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var uniques = uniquesBy(identity);\n\n /**\n * Using the provided iteratee, builds a function that will return an array comprised of the\n * unique elements of an array-like object. The values being compared are the ones returned by\n * the iteratee.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniques|uniques} if you don't need to transform your values before the\n * comparison.\n * @example\n * var data = [\n * {id: \"1\", name: \"John\"},\n * {id: \"4\", name: \"Jane\"},\n * {id: \"5\", name: \"Joe\"},\n * {id: \"1\", name: \"Mario\"},\n * {id: \"5\", name: \"Paolo\"},\n * ];\n * var uniquesById = _.uniquesBy(_.getKey(\"id\"));\n *\n * uniquesById(data) // => [{id: \"1\", name: \"John\"}, {id: \"4\", name: \"Jane\"}, {id: \"5\", name: \"Joe\"}]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.uniques|uniques}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function uniquesBy (iteratee) {\n return function (arrayLike) {\n var result = [];\n var len = arrayLike.length;\n\n for (var i = 0, seen = [], hasNaN = false, value; i < len; i++) {\n value = iteratee(arrayLike[i], i, arrayLike);\n\n if (value === value) { // eslint-disable-line no-self-compare\n if (seen.indexOf(value) === -1) {\n seen[seen.length] = value;\n result[result.length] = arrayLike[i];\n }\n } else if (!hasNaN) {\n hasNaN = true;\n result[result.length] = arrayLike[i];\n }\n }\n\n return result;\n };\n }\n\n /**\n * Builds a list of arrays out of the given array-like objects by pairing items with the same index.
\n * The received array-like objects will be truncated to the shortest length.\n * @example\n * _.zip(\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3],\n * [true, false, true]\n * ) // => [[\"a\", 1, true], [\"b\", 2, false], [\"c\", 3, true]]\n *\n * _.zip([1, 2, 3, 4], [5, 6, 7]) // => [[1, 5], [2, 6], [3, 7]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.transpose|transpose} for the reverse operation\n * @see {@link module:lamb.zipWithIndex|zipWithIndex}\n * @since 0.14.0\n * @param {...ArrayLike} arrayLike\n * @returns {Array}\n */\n var zip = compose(transpose, list);\n\n /**\n * \"{@link module:lamb.zip|Zips}\" an array-like object by pairing its values with their index.\n * @example\n * _.zipWithIndex([\"a\", \"b\", \"c\"]) // => [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\n var zipWithIndex = mapWith(binary(list));\n\n lamb.append = append;\n lamb.appendTo = appendTo;\n lamb.difference = difference;\n lamb.drop = drop;\n lamb.dropFrom = dropFrom;\n lamb.dropWhile = dropWhile;\n lamb.flatMap = flatMap;\n lamb.flatMapWith = flatMapWith;\n lamb.flatten = flatten;\n lamb.init = init;\n lamb.insert = insert;\n lamb.insertAt = insertAt;\n lamb.intersection = intersection;\n lamb.partition = partition;\n lamb.partitionWith = partitionWith;\n lamb.pluck = pluck;\n lamb.pluckKey = pluckKey;\n lamb.pull = pull;\n lamb.pullFrom = pullFrom;\n lamb.shallowFlatten = shallowFlatten;\n lamb.tail = tail;\n lamb.take = take;\n lamb.takeFrom = takeFrom;\n lamb.takeWhile = takeWhile;\n lamb.transpose = transpose;\n lamb.union = union;\n lamb.unionBy = unionBy;\n lamb.uniques = uniques;\n lamb.uniquesBy = uniquesBy;\n lamb.zip = zip;\n lamb.zipWithIndex = zipWithIndex;\n\n /**\n * Transforms an array-like object in a lookup table with the keys generated by the provided\n * iteratee, having as values the count of matches for the key.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 17},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n * var getAgeStatus = function (person) { return person.age >= 18 ? \"adult\" : \"minor\"; };\n *\n * _.count(persons, getAgeStatus) // => {\"adult\": 1, \"minor\": 3}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var count = _groupWith(function (a) {\n return a ? ++a : 1;\n });\n\n /**\n * A curried version of {@link module:lamb.count|count} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCityOrUnknown = _.adapter(_.getKey(\"city\"), _.always(\"Unknown\"));\n * var countByCity = _.countBy(getCityOrUnknown);\n *\n * countByCity(persons) // => {\"New York\": 2, \"Rome\": 1, \"Unknown\": 1}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.count|count}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var countBy = _curry2(count, true);\n\n /**\n * Transforms an array-like object into a lookup table using the provided iteratee as a grouping\n * criterion to generate keys and values.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCity = _.getKey(\"city\");\n * var personsByCity = _.group(persons, getCity);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"undefined\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @example Adding a custom value for missing keys:\n *\n * var getCityOrUnknown = _.adapter(getCity, _.always(\"Unknown\"));\n *\n * var personsByCity = _.group(persons, getCityOrUnknown);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"Unknown\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var group = _groupWith(function (a, b) {\n if (!a) {\n return [b];\n }\n\n a[a.length] = b;\n\n return a;\n });\n\n /**\n * A curried version of {@link module:lamb.group|group} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 18},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n *\n * var getAgeStatus = function (person) { return person.age > 20 ? \"over 20\" : \"under 20\"; };\n * var groupByAgeStatus = _.groupBy(getAgeStatus);\n *\n * var personsByAgeStatus = groupByAgeStatus(persons);\n *\n * // \"personsByAgeStatus\" holds:\n * // {\n * // \"under 20\": [\n * // {\"name\": \"Jane\", \"age\": 12},\n * // {\"name\": \"Mario\", \"age\": 18},\n * // {\"name\": \"Paolo\", \"age\": 15}\n * // ],\n * // \"over 20\": [\n * // {\"name\": \"John\", \"age\": 40}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.group|group}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var groupBy = _curry2(group, true);\n\n /**\n * Similar to {@link module:lamb.group|group}, but the generated lookup table will have\n * only one element of the original array-like object for each value.
\n * Should be used only when you're sure that your iteratee won't produce\n * duplicate keys, otherwise only the last evaluated element will be in the result.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"id\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"},\n * // \"4\": {id: 4, name: \"John\"}\n * // }\n *\n * @example Result of an iteratee producing a duplicate key:\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"name\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"John\": {\"id\": 4, \"name\": \"John\"},\n * // \"Jane\": {\"id\": 2, \"name\": \"Jane\"},\n * // \"Mario\": {\"id\": 3, \"name\": \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.indexBy|indexBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var index = _groupWith(function (a, b) {\n return b;\n });\n\n /**\n * A curried version of {@link module:lamb.index|index} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"}\n * ];\n * var indexByID = _.indexBy(_.getKey(\"id\"));\n *\n * var indexedUsers = indexByID(users);\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.index|index}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var indexBy = _curry2(index, true);\n\n lamb.count = count;\n lamb.countBy = countBy;\n lamb.group = group;\n lamb.groupBy = groupBy;\n lamb.index = index;\n lamb.indexBy = indexBy;\n\n /**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted\n * copy of an array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you\n * can also pass simple \"reader\" functions and default ascending sorters will be built for you.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used\n * in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type,\n * they will be compared as strings.\n *\n * @example Stable sort:\n * var persons = [\n * {\"name\": \"John\", \"surname\" :\"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"},\n * {\"name\": \"John\", \"surname\" :\"Moe\"},\n * {\"name\": \"Jane\", \"surname\": \"Foe\"}\n * ];\n *\n * var personsByName = _.sort(persons, _.getKey(\"name\"));\n *\n * // personsByName holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Stable multi-sort:\n * var personsByNameAscSurnameDesc = _.sort(\n * persons,\n * _.getKey(\"name\"),\n * _.sorterDesc(_.getKey(\"surname\"))\n * );\n *\n * // personsByNameAscSurnameDesc holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Using custom comparers:\n * var localeSorter = new Intl.Collator(\"it\");\n * var chars = [\"a\", \"è\", \"à\", \"é\", \"c\", \"b\", \"e\"];\n *\n * _.sort(chars, localeSorter) // => [\"a\", \"à\", \"b\", \"c\", \"e\", \"é\", \"è\"]\n *\n * var localeSorterDesc = _.sorterDesc(_.identity, localeSorter.compare);\n *\n * _.sort(chars, localeSorterDesc) // => [\"è\", \"é\", \"e\", \"c\", \"b\", \"à\", \"a\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {ArrayLike} arrayLike\n * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}]\n * @returns {Array}\n */\n function sort (arrayLike) {\n var criteria = _makeCriteria(_argsTail.apply(null, arguments));\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = {value: arrayLike[i], index: i};\n }\n\n result.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result[i] = result[i].value;\n }\n\n return result;\n }\n\n /**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example With simple values:\n * _.sortedInsert([], 1) // => [1]\n * _.sortedInsert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.sortedInsert([4, 2, 1], 3, _.sorterDesc()) // => [4, 3, 2, 1]\n *\n * @example With complex values:\n * var persons = [\n * {\"name\": \"jane\", \"surname\": \"doe\"},\n * {\"name\": \"John\", \"surname\": \"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * ];\n *\n * var getLowerCaseName = _.compose(\n * _.invoker(\"toLowerCase\"),\n * _.getKey(\"name\")\n * );\n *\n * var result = _.sortedInsert(\n * persons,\n * {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * getLowerCaseName\n * );\n *\n * // `result` holds:\n * // [\n * // {\"name\": \"jane\", \"surname\": \"doe\"},\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt} to insert the element\n * at a specific index\n * @since 0.27.0\n * @param {ArrayLike} arrayLike\n * @param {*} element\n * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}] - The sorting criteria\n * used to sort the array.\n * @returns {Array}\n */\n function sortedInsert (arrayLike, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n if (arguments.length === 1) {\n return result;\n }\n\n var len = arguments.length - 2;\n var sorters = Array(len);\n\n for (var i = 0; i < len; i++) {\n sorters[i] = arguments[i + 2];\n }\n\n var criteria = _makeCriteria(sorters);\n var idx = _getInsertionIndex(result, element, _compareWith(criteria), 0, result.length);\n\n result.splice(idx, 0, element);\n\n return result;\n }\n\n /**\n * Creates an ascending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.1.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorter = partial(_sorter, [_, false, _]);\n\n /**\n * Creates a descending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @since 0.15.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorterDesc = partial(_sorter, [_, true, _]);\n\n /**\n * Builds a partial application of {@link module:lamb.sort|sort} using the provided criteria.\n * The returned function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function,\n * but you can also pass simple \"reader\" functions and default ascending sorters will be built.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used in\n * the comparison.
\n * See {@link module:lamb.sort|sort} for more examples.\n *\n * @example\n * var sortAsNumbers = _.sortWith(parseFloat);\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * sortAsNumbers(weights) // => [\"1 Kg\", \"2 Kg\", \"7 Kg\", \"10 Kg\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}]\n * @returns {Function}\n */\n function sortWith () {\n var sorters = list.apply(null, arguments);\n\n return function (arrayLike) {\n return sort.apply(null, [arrayLike].concat(sorters));\n };\n }\n\n lamb.sort = sort;\n lamb.sortedInsert = sortedInsert;\n lamb.sorter = sorter;\n lamb.sorterDesc = sorterDesc;\n lamb.sortWith = sortWith;\n\n /**\n * Applies the given function to a list of arguments.\n * @example\n * _.application(_.sum, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.apply|apply}, {@link module:lamb.applyTo|applyTo}\n * @since 0.47.0\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\n function application (fn, args) {\n return fn.apply(this, Object(args));\n }\n\n /**\n * A left-curried version of {@link module:lamb.application|application}. Expects the function\n * to apply and builds a function waiting for the arguments array.\n * @example\n * var arrayMax = _.apply(Math.max);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.applyTo|applyTo}\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n var apply = _curry2(application);\n\n /**\n * A right-curried version of {@link module:lamb.application|application}. Expects an array-like\n * object to use as arguments and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyToData = _.applyTo(data);\n *\n * applyToData(_.sum) // => 7\n * applyToData(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.apply|apply}\n * @since 0.47.0\n * @param {ArrayLike} args\n * @returns {Function}\n */\n var applyTo = _curry2(application, true);\n\n /**\n * Builds a new function that passes only the specified amount of arguments to the original one.
\n * As {@link module:lamb.slice|slice} is used to extract the arguments, you can also\n * pass a negative arity.\n * @example\n * Math.max(10, 11, 45, 99) // => 99\n * _.aritize(Math.max, 2)(10, 11, 45, 99) // => 11\n *\n * @example Using a negative arity:\n * _.aritize(Math.max, -1)(10, 11, 45, 99) // => 45\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.binary|binary}, {@link module:lamb.unary|unary} for common use cases shortcuts\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\n function aritize (fn, arity) {\n return function () {\n var n = _toInteger(arity);\n var args = list.apply(null, arguments).slice(0, n);\n\n for (var i = args.length; i < n; i++) {\n args[i] = void 0;\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Decorates the received function so that it can be called with\n * placeholders to build a partial application of it.
\n * The difference with {@link module:lamb.partial|partial} is that, as long as\n * you call the generated function with placeholders, another partial application\n * of the original function will be built.
\n * The final application will happen when one of the generated functions is\n * invoked without placeholders, using the parameters collected so far.
\n * This function comes in handy when you need to build different specialized\n * functions starting from a basic one, but it's also useful when dealing with\n * optional parameters as you can decide to apply the function even if its arity\n * hasn't been entirely consumed.\n * @example Explaining the function's behaviour:\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + c;\n * });\n *\n * f(4, 3, 2) // => 9\n * f(4, _, 2)(3) // => 9\n * f(_, 3, _)(4, _)(2) // => 9\n *\n * @example Exploiting optional parameters:\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + (c || 0);\n * });\n *\n * var addFive = f(5, _);\n * addFive(2) // => 7\n *\n * var addNine = addFive(4, _);\n * addNine(11) // => 20\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.@@lamb/placeholder|@@lamb/placeholder}\n * @since 0.36.0\n * @param {Function} fn\n * @returns {Function}\n */\n function asPartial (fn) {\n return _asPartial(fn, []);\n }\n\n /**\n * Builds a function that passes only two arguments to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * _.list(1, 2, 3, 4, 5) // => [1, 2, 3, 4, 5]\n * _.binary(_.list)(1, 2, 3, 4, 5) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.unary|unary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function binary (fn) {\n return function (a, b) {\n return fn.call(this, a, b);\n };\n }\n\n /**\n * Accepts a series of functions and builds a new function. The functions in the series\n * will then be applied, in order, with the values received by the function built with\n * collect.
\n * The collected results will be returned in an array.\n * @example\n * var user = {\n * id: \"jdoe\",\n * name: \"John\",\n * surname: \"Doe\",\n * scores: [2, 4, 7]\n * };\n * var getIDAndLastScore = _.collect(_.getKey(\"id\"), _.getPath(\"scores.-1\"));\n *\n * getIDAndLastScore(user) // => [\"jdoe\", 7]\n *\n * @example\n * var minAndMax = _.collect(Math.min, Math.max);\n *\n * minAndMax(3, 1, -2, 5, 4, -1) // => [-2, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.35.0\n * @param {...Function} fn\n * @returns {Function}\n */\n function collect () {\n var functions = list.apply(null, arguments);\n\n return function () {\n return map(functions, applyTo(arguments));\n };\n }\n\n /**\n * Transforms the evaluation of the given function in the evaluation of a sequence of functions\n * expecting only one argument. Each function of the sequence is a partial application of the\n * original one, which will be applied when the specified (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryRight|curryRight}\n * for right currying.\n * @example\n * var makeWithKeys = _.curry(_.make);\n * var makePerson = makeWithKeys([\"name\", \"surname\"]);\n *\n * makePerson([\"John\", \"Doe\"]) // => {name: \"John\", surname: \"Doe\"};\n * makePerson([\"Mario\", \"Rossi\"]) // => {name: \"Mario\", surname: \"Rossi\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curry (fn, arity) {\n return _curry(fn, arity, false);\n }\n\n /**\n * Builds an auto-curried function. The resulting function can be called multiple times with\n * any number of arguments, and the original function will be applied only when the specified\n * (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryableRight|curryableRight}\n * for right currying.\n * @example\n * var collectFourElements = _.curryable(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2)(3, 4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3, 4, 5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3)(4, 5) // => [2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.6.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryable (fn, arity) {\n return _curry(fn, arity, false, true);\n }\n\n /**\n * Same as {@link module:lamb.curryable|curryable}, but currying starts from the rightmost argument.\n * @example\n * var collectFourElements = _.curryableRight(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2)(3, 4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3, 4, 5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3)(4, 5) // => [5, 4, 3, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryable|curryable}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryableRight (fn, arity) {\n return _curry(fn, arity, true, true);\n }\n\n /**\n * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var makeWithValues = _.curryRight(_.make);\n * var makeJohnDoe = makeWithValues([\"John\", \"Doe\"]);\n *\n * makeJohnDoe([\"name\", \"surname\"]) // => {name: \"John\", surname: \"Doe\"};\n * makeJohnDoe([\"firstName\", \"lastName\"]) // => {firstName: \"John\", lastName: \"Doe\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curry|curry}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryRight (fn, arity) {\n return _curry(fn, arity, true);\n }\n\n /**\n * Returns a function that will execute the given function only if it stops being called for the\n * specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call\n * happens immediately.\n * @example A common use case of debounce in a browser environment:\n * var updateLayout = function () {\n * // some heavy DOM operations here\n * };\n *\n * window.addEventListener(\"resize\", _.debounce(updateLayout, 200), false);\n *\n * // The resize event is fired repeteadly until the user stops resizing the\n * // window, while the `updateLayout` function is called only once: 200 ms\n * // after he stopped.\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.throttle|throttle}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds\n * @returns {Function}\n */\n function debounce (fn, timespan) {\n var timeoutID;\n\n return function () {\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(this, args);\n }.bind(this);\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n }\n\n /**\n * Returns a function that applies the original function with the arguments in reverse order.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n * _.flip(_.list)(1, 2, 3) // => [3, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n function flip (fn) {\n return function () {\n var args = list.apply(null, arguments).reverse();\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Builds a function that returns the argument received at the given index.
\n * As with {@link module:lamb.getAt|getAt} negative indexes are allowed.
\n * The resulting function will return undefined if no arguments are\n * passed or if the index is out of bounds.\n * @example\n * var getFirstArg = getArgAt(0);\n * var getLastArg = getArgAt(-1);\n *\n * getFirstArg(1, 2, 3) // => 1\n * getLastArg(1, 2, 3) // => 3\n *\n * getArgAt()(1, 2, 3) // => undefined\n * getArgAt(6)(1, 2, 3) // => undefined\n * getArgAt(1)() // => undefined\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.17.0\n * @param {Number} idx\n * @returns {Function}\n */\n function getArgAt (idx) {\n return function () {\n return arguments[_toNaturalIndex(idx, arguments.length)];\n };\n }\n\n /**\n * Builds a function that will invoke the given method name on any received object and\n * return the result. If no method with such name is found the function will return\n * undefined.
\n * Along with the method name it's possible to supply some arguments that will be bound to the\n * method call. Further arguments can also be passed when the function is actually called, and\n * they will be concatenated to the bound ones.
\n * Returning undefined is a behaviour meant to quickly create a case for\n * {@link module:lamb.adapter|adapter} without the need to check for the existence of the\n * desired method.
\n * See also {@link module:lamb.generic|generic} to create functions out of object methods.\n * @example Basic polymorphism with invoker:\n * var polySlice = _.invoker(\"slice\");\n *\n * polySlice([1, 2, 3, 4, 5], 1, 3) // => [2, 3]\n * polySlice(\"Hello world\", 1, 3) // => \"el\"\n *\n * @example With bound arguments:\n * var substrFrom2 = _.invoker(\"substr\", 2);\n * substrFrom2(\"Hello world\") // => \"llo world\"\n * substrFrom2(\"Hello world\", 5) // => \"llo w\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invokerOn|invokerOn}\n * @since 0.1.0\n * @param {String} methodName\n * @param {...*} [boundArg]\n * @returns {Function}\n */\n function invoker (methodName) {\n return partial(_invoker, [_argsTail.apply(null, arguments), methodName]);\n }\n\n /**\n * Accepts an object and builds a function expecting a method name, and optionally arguments,\n * to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the\n * function will return undefined.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var arr = [1, 2, 3, 4, 5];\n * var invokerOnArr = _.invokerOn(arr);\n *\n * invokerOnArr(\"filter\", isEven) // => [2, 4]\n * invokerOnArr(\"slice\", 1, 3) // => [2, 3]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.15.0\n * @param {Object} target\n * @returns {Function}\n */\n function invokerOn (target) {\n return partial(_invoker, [[], _, target]);\n }\n\n /**\n * Builds a function that allows to map over the received arguments before applying them\n * to the original one.\n * @example\n * var sumArray = _.reduceWith(_.sum);\n * var sumArgs = _.compose(sumArray, _.list);\n *\n * sumArgs(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, [_, 2]);\n * var sumSquares = _.mapArgs(sumArgs, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.tapArgs|tapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\n function mapArgs (fn, mapper) {\n return compose(apply(fn), mapWith(mapper), list);\n }\n\n /**\n * Creates a pipeline of functions, where each function consumes the result of the previous one.\n * @example\n * var square = _.partial(Math.pow, [_, 2]);\n * var getMaxAndSquare = _.pipe(Math.max, square);\n *\n * getMaxAndSquare(3, 5) // => 25\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.compose|compose}\n * @since 0.1.0\n * @param {...Function} fn\n * @returns {Function}\n */\n var pipe = flip(compose);\n\n /**\n * Builds a function that allows to \"tap\" into the arguments of the original one.\n * This allows to extract simple values from complex ones, transform arguments or simply intercept them.\n * If a \"tapper\" isn't found the argument is passed as it is.\n * @example\n * var someObject = {count: 5};\n * var someArrayData = [2, 3, 123, 5, 6, 7, 54, 65, 76, 0];\n * var getDataAmount = _.tapArgs(_.sum, [_.getKey(\"count\"), _.getKey(\"length\")]);\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.mapArgs|mapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {Function[]} tappers\n * @returns {Function}\n */\n function tapArgs (fn, tappers) {\n return function () {\n var len = arguments.length;\n var tappersLen = tappers.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(i < tappersLen ? tappers[i](arguments[i]) : arguments[i]);\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Returns a function that will invoke the passed function at most once in the given timespan.
\n * The first call in this case happens as soon as the function is invoked; see also\n * {@link module:lamb.debounce|debounce} for a different behaviour where the first call is delayed.\n * @example\n * var log = _.throttle(console.log.bind(console), 5000);\n *\n * log(\"Hi\"); // console logs \"Hi\"\n * log(\"Hi again\"); // nothing happens\n * // after five seconds\n * log(\"Hello world\"); // console logs \"Hello world\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.debounce|debounce}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds.\n * @returns {Function}\n */\n function throttle (fn, timespan) {\n var result;\n var lastCall = 0;\n\n return function () {\n var now = Date.now();\n\n if (now - lastCall >= timespan) {\n lastCall = now;\n result = fn.apply(this, arguments);\n }\n\n return result;\n };\n }\n\n /**\n * Builds a function that passes only one argument to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * _.map(weights, _.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.binary|binary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function unary (fn) {\n return function (a) {\n return fn.call(this, a);\n };\n }\n\n lamb.application = application;\n lamb.apply = apply;\n lamb.applyTo = applyTo;\n lamb.aritize = aritize;\n lamb.asPartial = asPartial;\n lamb.binary = binary;\n lamb.collect = collect;\n lamb.curry = curry;\n lamb.curryRight = curryRight;\n lamb.curryable = curryable;\n lamb.curryableRight = curryableRight;\n lamb.debounce = debounce;\n lamb.flip = flip;\n lamb.getArgAt = getArgAt;\n lamb.invoker = invoker;\n lamb.invokerOn = invokerOn;\n lamb.mapArgs = mapArgs;\n lamb.pipe = pipe;\n lamb.tapArgs = tapArgs;\n lamb.throttle = throttle;\n lamb.unary = unary;\n\n /**\n * Creates an array with all the enumerable properties of the given object.\n * @example Showing the difference with {@link module:lamb.keys|keys}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.keys|keys}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {String[]}\n */\n var enumerables = _unsafeKeyListFrom(_safeEnumerables);\n\n /**\n * Builds an object from a list of key / value pairs like the one\n * returned by {@link module:lamb.pairs|pairs} or {@link module:lamb.ownPairs|ownPairs}.
\n * In case of duplicate keys the last key / value pair is used.\n * @example\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"c\", 3]]) // => {\"a\": 1, \"b\": 2, \"c\": 3}\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"a\", 3]]) // => {\"a\": 3, \"b\": 2}\n * _.fromPairs([[1], [void 0, 2], [null, 3]]) // => {\"1\": undefined, \"undefined\": 2, \"null\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.ownPairs|ownPairs}, {@link module:lamb.pairs|pairs}\n * @since 0.8.0\n * @param {Array>} pairsList\n * @returns {Object}\n */\n function fromPairs (pairsList) {\n var result = {};\n\n forEach(pairsList, function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n }\n\n /**\n * Makes an object immutable by recursively calling [Object.freeze]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze}\n * on its members.
\n * Any attempt to extend or modify the object can throw a TypeError or fail silently,\n * depending on the environment and the [strict mode]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode} directive.\n * @example\n * var user = _.immutable({\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\"\n * },\n * luckyNumbers: [13, 17]\n * });\n *\n * // All of these statements will fail and possibly\n * // throw a TypeError (see the function description)\n * user.name = \"Joe\";\n * delete user.name;\n * user.newProperty = [];\n * user.login.password = \"foo\";\n * user.luckyNumbers.push(-13);\n *\n * @memberof module:lamb\n * @category Object\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Object}\n */\n function immutable (obj) {\n return _immutable(obj, []);\n }\n\n /**\n * Retrieves the list of the own enumerable properties of an object.
\n * Although [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * is already present in ECMAScript 5, its behaviour changed in the subsequent specifications\n * of the standard.
\n * This function shims the ECMAScript 6 version, by forcing a conversion to\n * object for any value but null and undefined.\n * @example Showing the difference with {@link module:lamb.enumerables|enumerables}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.enumerables(foo) // => [\"d\", \"a\"]\n * _.keys(foo) // => [\"d\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.enumerables|enumerables}\n * @since 0.25.1\n * @param {Object} obj\n * @returns {String[]}\n */\n var keys = _unsafeKeyListFrom(_safeKeys);\n\n /**\n * Builds an object from the two given lists, using the first one as keys and the last\n * one as values.
\n * If the list of keys is longer than the values one, the keys will be created with\n * undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.\n * @example\n * _.make([\"a\", \"b\", \"c\"], [1, 2, 3]) // => {a: 1, b: 2, c: 3}\n * _.make([\"a\", \"b\", \"c\"], [1, 2]) // => {a: 1, b: 2, c: undefined}\n * _.make([\"a\", \"b\"], [1, 2, 3]) // => {a: 1, b: 2}\n * _.make([null, void 0, 2], [1, 2, 3]) // => {\"null\": 1, \"undefined\": 2, \"2\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.tear|tear}, {@link module:lamb.tearOwn|tearOwn} for the reverse operation\n * @since 0.8.0\n * @param {String[]} names\n * @param {ArrayLike} values\n * @returns {Object}\n */\n function make (names, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = names.length; i < len; i++) {\n result[names[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n }\n\n /**\n * Creates a new object by applying the given function\n * to all enumerable properties of the source one.\n * @example\n * var weights = {\n * john: \"72.5 Kg\",\n * jane: \"52.3 Kg\"\n * };\n *\n * _.mapValues(weights, parseFloat) // => {john: 72.5, jane: 52.3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValuesWith|mapValuesWith}\n * @since 0.54.0\n * @param {Object} source\n * @param {ObjectIteratorCallback} fn\n * @returns {Object}\n */\n function mapValues (source, fn) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n result[key] = fn(source[key], key, source);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.mapValues|mapValues}.
\n * Expects a mapping function to build a new function waiting for the\n * object to act upon.\n * @example\n * var incValues = _.mapValuesWith(_.add(1));\n * var results = {\n * first: 10,\n * second: 5,\n * third: 3\n * };\n *\n * incValues(results) // => {first: 11, second: 6, third: 4}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValues|mapValues}\n * @since 0.54.0\n * @function\n * @param {ObjectIteratorCallback} fn\n * @returns {Function}\n */\n var mapValuesWith = _curry2(mapValues, true);\n\n /**\n * Merges the enumerable properties of the provided sources into a new object.
\n * In case of key homonymy each source has precedence over the previous one.\n * @example\n * _.merge({a: 1}, {b: 3, c: 4}, {b: 5}) // => {a: 1, b: 5, c: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.merge([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.merge(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.merge({a: 2}, 99, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mergeOwn|mergeOwn} to merge own properties only\n * @since 0.10.0\n * @function\n * @param {...Object} source\n * @returns {Object}\n */\n var merge = partial(_merge, [enumerables]);\n\n /**\n * Same as {@link module:lamb.merge|merge}, but only the own properties of the\n * sources are taken into account.\n * @example Showing the difference with merge:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * var bar = {d: 4};\n *\n * _.merge(foo, bar) // => {a: 1, b: 2, c: 3, d: 4}\n * _.mergeOwn(foo, bar) // => {c: 3, d: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.mergeOwn([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.mergeOwn(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.mergeOwn({a: 2}, 99, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.merge|merge} to merge all enumerable properties\n * @since 0.12.0\n * @function\n * @param {...Object} source\n * @returns {Object}\n */\n var mergeOwn = partial(_merge, [keys]);\n\n /**\n * Same as {@link module:lamb.pairs|pairs}, but only the own enumerable properties of the object are\n * taken into account.
\n * See also {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example Showing the difference with pairs:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.pairs(foo) // => [[\"c\", 3], [\"b\", 2], [\"a\", 1]]\n * _.ownPairs(foo) // => [[\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pairs|pairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var ownPairs = _pairsFrom(keys);\n\n /**\n * Same as {@link module:lamb.values|values}, but only the own enumerable properties of the object are\n * taken into account.
\n * @example Showing the difference with values:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.values(foo) // => [3, 2, 1]\n * _.ownValues(foo) // => [3]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.values|values}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var ownValues = _valuesFrom(keys);\n\n /**\n * Converts an object into an array of key / value pairs of its enumerable properties.
\n * See also {@link module:lamb.ownPairs|ownPairs} for picking only the own enumerable\n * properties and {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example\n * _.pairs({a: 1, b: 2, c: 3}) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownPairs|ownPairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var pairs = _pairsFrom(enumerables);\n\n /**\n * Returns an object containing only the specified properties of the given object.
\n * Non existent properties will be ignored.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.pick(user, [\"name\", \"age\"]) // => {\"name\": \"john\", \"age\": 30};\n * _.pick(user, [\"name\", \"email\"]) // => {\"name\": \"john\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pickIf|pickIf}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\n function pick (source, whitelist) {\n var result = {};\n\n for (var i = 0, len = whitelist.length, key; i < len; i++) {\n key = whitelist[i];\n\n if (has(source, key)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be included in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var pickIfIsString = _.pickIf(_.isType(\"String\"));\n *\n * pickIfIsString(user) // => {name: \"john\", surname: \"doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n function pickIf (predicate) {\n return function (source) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n if (predicate(source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n }\n\n /**\n * A curried version of {@link module:lamb.pick|pick}, expecting a whitelist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.pickKeys([\"id\", \"active\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var select = _.compose(_.mapWith, _.pickKeys);\n * var selectUserInfo = select([\"id\", \"active\"]);\n *\n * selectUserInfo(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickIf|pickIf}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.35.0\n * @param {String[]} whitelist\n * @returns {Function}\n */\n var pickKeys = _curry2(pick, true);\n\n /**\n * Creates a copy of the given object with its enumerable keys renamed as\n * indicated in the provided lookup table.\n * @example\n * var person = {\"firstName\": \"John\", \"lastName\": \"Doe\"};\n * var keysMap = {\"firstName\": \"name\", \"lastName\": \"surname\"};\n *\n * _.rename(person, keysMap) // => {\"name\": \"John\", \"surname\": \"Doe\"}\n *\n * @example It's safe using it to swap keys:\n * var keysMap = {\"firstName\": \"lastName\", \"lastName\": \"firstName\"};\n *\n * _.rename(person, keysMap) // => {\"lastName\": \"John\", \"firstName\": \"Doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.renameKeys|renameKeys}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} source\n * @param {Object} keysMap\n * @returns {Object}\n */\n function rename (source, keysMap) {\n keysMap = Object(keysMap);\n var result = {};\n var oldKeys = enumerables(source);\n\n for (var prop in keysMap) {\n if (~oldKeys.indexOf(prop)) {\n result[keysMap[prop]] = source[prop];\n }\n }\n\n for (var i = 0, len = oldKeys.length, key; i < len; i++) {\n key = oldKeys[i];\n\n if (!(key in keysMap || key in result)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.rename|rename} expecting a\n * keysMap to build a function waiting for the object to act upon.\n * @example\n * var persons = [\n * {\"firstName\": \"John\", \"lastName\": \"Doe\"},\n * {\"first_name\": \"Mario\", \"last_name\": \"Rossi\"},\n * ];\n * var normalizeKeys = _.renameKeys({\n * \"firstName\": \"name\",\n * \"first_name\": \"name\",\n * \"lastName\": \"surname\",\n * \"last_name\": \"surname\"\n * });\n *\n * _.map(persons, normalizeKeys) // =>\n * // [\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} keysMap\n * @returns {Function}\n */\n var renameKeys = _curry2(rename, true);\n\n /**\n * Uses the provided function as a keysMap generator and returns\n * a function expecting the object whose keys we want to {@link module:lamb.rename|rename}.\n * @example\n * var person = {\"NAME\": \"John\", \"SURNAME\": \"Doe\"};\n * var arrayToLower = _.mapWith(_.invoker(\"toLowerCase\"));\n * var makeLowerKeysMap = function (source) {\n * var sourceKeys = _.keys(source);\n *\n * return _.make(sourceKeys, arrayToLower(sourceKeys));\n * };\n * var lowerKeysFor = _.renameWith(makeLowerKeysMap);\n *\n * lowerKeysFor(person) // => {\"name\": \"John\", \"surname\": \"doe\"};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameKeys|renameKeys}\n * @since 0.26.0\n * @param {Function} fn\n * @returns {Function}\n */\n function renameWith (fn) {\n return function (source) {\n return rename(source, fn(source));\n };\n }\n\n /**\n * Returns a copy of the source object without the specified properties.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.skip(user, [\"name\", \"age\"]) // => {surname: \"doe\"};\n * _.skip(user, [\"name\", \"email\"]) // => {surname: \"doe\", age: 30};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.skipKeys|skipKeys}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\n function skip (source, blacklist) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n var props = make(blacklist, []);\n\n for (var key in source) {\n if (!(key in props)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be omitted in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var skipIfIstring = _.skipIf(_.isType(\"String\"));\n *\n * skipIfIstring(user) // => {age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n var skipIf = compose(pickIf, not);\n\n /**\n * A curried version of {@link module:lamb.skip|skip}, expecting a blacklist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.skipKeys([\"name\", \"surname\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var discard = _.compose(_.mapWith, _.skipKeys);\n * var discardNames = discard([\"name\", \"surname\"]);\n *\n * discardNames(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.35.0\n * @param {String[]} blacklist\n * @returns {Function}\n */\n var skipKeys = _curry2(skip, true);\n\n /**\n * Tears an object apart by transforming it in an array of two lists: one containing\n * its enumerable keys, the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source\n * object will be unharmed.\n * @example\n * _.tear({a: 1, b: 2, c: 3}) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tearOwn|tearOwn}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tear = _tearFrom(enumerables);\n\n /**\n * Same as {@link module:lamb.tear|tear}, but only the own properties of the object are\n * taken into account.\n * @example Showing the difference with tear:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.tear(foo) // => [[\"c\", \"b\", \"a\"], [3, 2, 1]]\n * _.tearOwn(foo) // => [[\"c\"], [3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tear|tear}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tearOwn = _tearFrom(keys);\n\n /**\n * Generates an array with the values of the enumerable properties of the given object.
\n * See also {@link module:lamb.ownValues|ownValues} to pick only from the own properties of the object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.values(user) // => [\"john\", \"doe\", 30]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownValues|ownValues}\n * @since 0.1.0\n * @param {Object} obj\n * @returns {Array}\n */\n var values = _valuesFrom(enumerables);\n\n lamb.enumerables = enumerables;\n lamb.fromPairs = fromPairs;\n lamb.immutable = immutable;\n lamb.keys = keys;\n lamb.make = make;\n lamb.mapValues = mapValues;\n lamb.mapValuesWith = mapValuesWith;\n lamb.merge = merge;\n lamb.mergeOwn = mergeOwn;\n lamb.ownPairs = ownPairs;\n lamb.ownValues = ownValues;\n lamb.pairs = pairs;\n lamb.pick = pick;\n lamb.pickIf = pickIf;\n lamb.pickKeys = pickKeys;\n lamb.rename = rename;\n lamb.renameKeys = renameKeys;\n lamb.renameWith = renameWith;\n lamb.skip = skip;\n lamb.skipIf = skipIf;\n lamb.skipKeys = skipKeys;\n lamb.tear = tear;\n lamb.tearOwn = tearOwn;\n lamb.values = values;\n\n /**\n * Builds a checker function meant to be used with\n * {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to\n * compare their values. In other words all the received keyPaths will be\n * passed as arguments to the predicate to run the test.
\n * If you want to run the same single property check with multiple properties, you should build\n * multiple checkers and combine them with {@link module:lamb.validate|validate}.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\",\n * passwordConfirm: \"abc123\"\n * }\n * };\n * var pwdMatch = _.checker(\n * _.is,\n * \"Passwords don't match\",\n * [\"login.password\", \"login.passwordConfirm\"]\n * );\n *\n * pwdMatch(user) // => []\n *\n * var newUser = _.setPathIn(user, \"login.passwordConfirm\", \"avc123\");\n *\n * pwdMatch(newUser) // => [\"Passwords don't match\", [\"login.password\", \"login.passwordConfirm\"]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}, {@link module:lamb.validateWith|validateWith}\n * @since 0.1.0\n * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of keys, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Function} A checker function which returns an error in the form\n * [\"message\", [\"propertyA\", \"propertyB\"]] or an empty array.\n */\n function checker (predicate, message, keyPaths, pathSeparator) {\n return function (obj) {\n var getValues = partial(getPathIn, [obj, _, pathSeparator]);\n\n return predicate.apply(obj, map(keyPaths, getValues)) ? [] : [message, keyPaths];\n };\n }\n\n /**\n * Verifies the existence of a property in an object.\n * @example\n * var user1 = {name: \"john\"};\n *\n * _.has(user1, \"name\") // => true\n * _.has(user1, \"surname\") // => false\n * _.has(user1, \"toString\") // => true\n *\n * var user2 = Object.create(null);\n *\n * // not inherited through the prototype chain\n * _.has(user2, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function has (obj, key) {\n if (typeof obj !== \"object\" && !isUndefined(obj)) {\n obj = Object(obj);\n }\n\n return key in obj;\n }\n\n /**\n * Curried version of {@link module:lamb.has|has}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {};\n * var hasName = _.hasKey(\"name\");\n *\n * hasName(user1) // => true\n * hasName(user2) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.has|has}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasKey = _curry2(has, true);\n\n /**\n * Builds a predicate expecting an object to check against the given key / value pair.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var hasTheCorrectAnswer = _.hasKeyValue(\"answer\", 42);\n *\n * hasTheCorrectAnswer({answer: 2}) // false\n * hasTheCorrectAnswer({answer: 42}) // true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasPathValue|hasPathValue}\n * @since 0.1.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n function hasKeyValue (key, value) {\n return function (obj) {\n return isUndefined(value) ? has(obj, key) && obj[key] === value : areSVZ(value, obj[key]);\n };\n }\n\n /**\n * Verifies if an object has the specified property and that the property isn't inherited through\n * the prototype chain.
\n * @example Comparison with has:\n * var user = {name: \"john\"};\n *\n * _.has(user, \"name\") // => true\n * _.has(user, \"surname\") // => false\n * _.has(user, \"toString\") // => true\n *\n * _.hasOwn(user, \"name\") // => true\n * _.hasOwn(user, \"surname\") // => false\n * _.hasOwn(user, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var hasOwn = generic(_objectProto.hasOwnProperty);\n\n /**\n * Curried version of {@link module:lamb.hasOwn|hasOwn}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user = {name: \"john\"};\n * var hasOwnName = _.hasOwnKey(\"name\");\n * var hasOwnToString = _.hasOwnToString(\"toString\");\n *\n * hasOwnName(user) // => true\n * hasOwnToString(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwn|hasOwn}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasOwnKey = _curry2(hasOwn, true);\n\n /**\n * Builds a predicate to check if the given path exists in an object and holds the desired value.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * personal: {\n * age: 25,\n * gender: \"M\"\n * },\n * scores: [\n * {id: 1, value: 10, passed: false},\n * {id: 2, value: 20, passed: false},\n * {id: 3, value: 30, passed: true}\n * ]\n * };\n *\n * var isMale = _.hasPathValue(\"personal.gender\", \"M\");\n * var hasPassedFirstTest = _.hasPathValue(\"scores.0.passed\", true);\n * var hasPassedLastTest = _.hasPathValue(\"scores.-1.passed\", true);\n *\n * isMale(user) // => true\n * hasPassedFirstTest(user) // => false\n * hasPassedLastTest(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKeyValue|hasKeyValue}\n * @since 0.41.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function hasPathValue (path, value, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return pathInfo.isValid && areSVZ(pathInfo.target, value);\n };\n }\n\n /**\n * Builds a predicate to check if the given key satisfies the desired condition\n * on an object.\n * @example\n * var users = [\n * {name: \"John\", age: 25},\n * {name: \"Jane\", age: 15},\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n *\n * isAdult(users[0]) // => true\n * isAdult(users[1]) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathSatisfies|pathSatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} key\n * @returns {Function}\n */\n function keySatisfies (predicate, key) {\n return function (obj) {\n return predicate.call(this, obj[key]);\n };\n }\n\n /**\n * Builds a partial application of {@link module:lamb.pathExistsIn|pathExistsIn} using the given\n * path and the optional separator. The resulting function expects the object to check.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * var hasCity = _.pathExists(\"address.city\");\n * var hasCountry = _.pathExists(\"address.country\");\n * var hasAtLeastThreeScores = _.pathExists(\"scores.2\");\n *\n * hasCity(user) // => true\n * hasCountry(user) // => false\n * hasAtLeastThreeScores(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var pathExists = _makePartial3(pathExistsIn);\n\n /**\n * Checks if the provided path exists in the given object.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * _.pathExistsIn(user, \"address.city\") // => true\n * _.pathExistsIn(user, \"address.country\") // => false\n * _.pathExistsIn(user, \"scores.1\") // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathExists|pathExists}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {Object} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Boolean}\n */\n function pathExistsIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).isValid;\n }\n\n /**\n * Builds a predicate that verifies if a condition is satisfied for the given\n * path in an object.
\n * Like the other \"path functions\" you can use integers in the path, even\n * negative ones, to refer to array-like object indexes, but the priority will\n * be given to existing object keys.\n * @example\n * var user = {\n * name: \"John\",\n * performance: {\n * scores: [1, 5, 10]\n * }\n * };\n *\n * var gotAnHighScore = _.pathSatisfies(_.contains(10), \"performance.scores\");\n * var hadAGoodStart = _.pathSatisfies(_.isGT(6), \"performance.scores.0\");\n *\n * gotAnHighScore(user) // => true\n * hadAGoodStart(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.keySatisfies|keySatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function pathSatisfies (predicate, path, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return predicate.call(this, pathInfo.target);\n };\n }\n\n /**\n * Validates an object with the given list of {@link module:lamb.checker|checker} functions.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * _.validate(user1, userCheckers) // => []\n * _.validate(user2, userCheckers) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by\n * {@link module:lamb.checker|checker}, or an empty array.\n */\n function validate (obj, checkers) {\n return reduce(checkers, function (errors, _checker) {\n var result = _checker(obj);\n\n result.length && errors.push(result);\n\n return errors;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of\n * {@link module:lamb.checker|checkers} and returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n * var validateUser = _.validateWith(userCheckers);\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * validateUser(user1) // => []\n * validateUser(user2) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Function[]} checkers\n * @returns {Function}\n */\n var validateWith = _curry2(validate, true);\n\n lamb.checker = checker;\n lamb.has = has;\n lamb.hasKey = hasKey;\n lamb.hasKeyValue = hasKeyValue;\n lamb.hasOwn = hasOwn;\n lamb.hasOwnKey = hasOwnKey;\n lamb.hasPathValue = hasPathValue;\n lamb.keySatisfies = keySatisfies;\n lamb.pathExists = pathExists;\n lamb.pathExistsIn = pathExistsIn;\n lamb.pathSatisfies = pathSatisfies;\n lamb.validate = validate;\n lamb.validateWith = validateWith;\n\n /**\n * Pads a string to the desired length with the given char starting from the beginning of the string.\n * @example\n * _.padLeft(\"foo\", \"-\", 0) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", -1) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", 5) // => \"--foo\"\n * _.padLeft(\"foo\", \"-\", 3) // => \"foo\"\n * _.padLeft(\"foo\", \"ab\", 7) // => \"aaaafoo\"\n * _.padLeft(\"foo\", \"\", 5) // => \"foo\"\n * _.padLeft(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padRight|padRight}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padLeft (source, char, len) {\n return _getPadding(source, char, len) + source;\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the end of the string.\n * @example\n * _.padRight(\"foo\", \"-\", 0) // => \"foo\"\n * _.padRight(\"foo\", \"-\", -1) // => \"foo\"\n * _.padRight(\"foo\", \"-\", 5) // => \"foo--\"\n * _.padRight(\"foo\", \"-\", 3) // => \"foo\"\n * _.padRight(\"foo\", \"ab\", 7) // => \"fooaaaa\"\n * _.padRight(\"foo\", \"\", 5) // => \"foo\"\n * _.padRight(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padLeft|padLeft}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padRight (source, char, len) {\n return source + _getPadding(source, char, len);\n }\n\n /**\n * Builds a new string by repeating the source string the desired amount of times.
\n * Note that unlike the current ES6 proposal for\n * [String.prototype.repeat]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat},\n * this function doesn't throw a RangeError if times is negative,\n * but returns an empty string instead.\n * @example\n * _.repeat(\"Hello\", -1) // => \"\"\n * _.repeat(\"Hello\", 1) // => \"Hello\"\n * _.repeat(\"Hello\", 3) // => \"HelloHelloHello\"\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function repeat (source, times) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"string\");\n }\n\n return _repeat(source, Math.floor(times));\n }\n\n /**\n * Builds a predicate expecting a string to test against the given regular expression pattern.\n * @example\n * var hasNumbersOnly = _.testWith(/^\\d+$/);\n *\n * hasNumbersOnly(\"123\") // => true\n * hasNumbersOnly(\"123 Kg\") // => false\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {RegExp} pattern\n * @returns {Function}\n */\n function testWith (pattern) {\n return function (s) {\n return _search(s, pattern) !== -1;\n };\n }\n\n lamb.padLeft = padLeft;\n lamb.padRight = padRight;\n lamb.repeat = repeat;\n lamb.testWith = testWith;\n\n /* istanbul ignore next */\n if (typeof exports === \"object\") {\n module.exports = lamb;\n } else if (typeof define === \"function\" && define.amd) {\n define(function () {\n return lamb;\n });\n } else {\n host.lamb = lamb;\n }\n})(this);\n\n/**\n * @callback AccumulatorCallback\n * @global\n * @param {*} previousValue - The value returned it the last execution of the accumulator or, in the first\n * iteration, the {@link module:lamb.reduce|initialValue} if supplied.\n * @param {*} currentValue - The value being processed in the current iteration.\n * @param {Number} idx - The index of the element being processed.\n * @param {ArrayLike} arrayLike - The list being traversed.\n */\n\n/**\n * The built-in arguments object.\n * @typedef {arguments} arguments\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments|arguments} in Mozilla documentation.\n */\n\n/**\n * The built-in Array object.\n * @typedef {Array} Array\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array|Array} in Mozilla documentation.\n */\n\n/**\n * Any array-like object.\n * @typedef {Array|String|arguments|?} ArrayLike\n * @global\n */\n\n/**\n * The built-in Boolean object.\n * @typedef {Boolean} Boolean\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean|Boolean} in Mozilla documentation.\n */\n\n/**\n * The built-in Date object.\n * @typedef {Date} Date\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date|Date} in Mozilla documentation.\n */\n\n/**\n * The built-in Function object.\n * @typedef {Function} function\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function|Function} and\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions|Functions} in Mozilla documentation.\n */\n\n/**\n * @callback ListIteratorCallback\n * @global\n * @param {*} element - The element being evaluated.\n * @param {Number} idx - The index of the element within the list.\n * @param {ArrayLike} arrayLike - The list being traversed.\n */\n\n/**\n * The built-in Number object.\n * @typedef {Number} Number\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number|Number} in Mozilla documentation.\n */\n\n/**\n * The built-in Object object.\n * @typedef {Object} Object\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object|Object} in Mozilla documentation.\n */\n\n/**\n * @callback ObjectIteratorCallback\n * @global\n * @param {*} value - The value of the current property.\n * @param {String} key - The property name.\n * @param {Object} source - The object being traversed.\n */\n\n/**\n * The built-in RegExp object.\n * @typedef {RegExp} RegExp\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp|RegExp} in Mozilla documentation.\n */\n\n/**\n * Represents a sorting criteria used by {@link module:lamb.sortedInsert|sortedInsert},\n * {@link module:lamb.sort|sort} and {@link module:lamb.sortWith|sortWith}, and it's\n * usually built using {@link module:lamb.sorter|sorter} and {@link module:lamb.sorterDesc|sorterDesc}.\n * @typedef {Sorter} Sorter\n * @global\n * @property {Boolean} isDescending\n * @property {Function} compare\n */\n\n/**\n * The built-in String object.\n * @typedef {String} String\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String|String} in Mozilla documentation.\n */\n\n/**\n * The built-in primitive value undefined\n * @typedef {Undefined} Undefined\n * @global\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined|undefined} in Mozilla documentation.\n */\n"]} \ No newline at end of file diff --git a/license.txt b/license.txt index ab9b924..b034664 100644 --- a/license.txt +++ b/license.txt @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015-2017 Andrea Scartabelli +Copyright (c) 2015-2018 Andrea Scartabelli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/package-lock.json b/package-lock.json index 5214b24..1eace6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamb", - "version": "0.55.0-alpha.3", + "version": "0.55.0-alpha.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 83a178b..7333d0f 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "coveralls": "gulp coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" }, "tonicExample": "var _ = require('lamb');", - "version": "0.55.0-alpha.3", + "version": "0.55.0-alpha.4", "devDependencies": { "coveralls": "^3.0.0", "gulp": "^3.9.1", diff --git a/src/accessors.js b/src/accessors.js index 5bb2c7a..bfea6af 100644 --- a/src/accessors.js +++ b/src/accessors.js @@ -63,9 +63,9 @@ function getIn (obj, key) { * @category Array * @see {@link module:lamb.getAt|getAt} * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts. + * @since 0.23.0 * @param {ArrayLike} arrayLike * @param {Number} index - * @since 0.23.0 * @returns {*} */ function getIndex (arrayLike, index) { @@ -222,7 +222,8 @@ var head = getAt(0); var last = getAt(-1); /** - * Builds a function that creates a copy of an array-like object with the given + * A curried version of {@link module:lamb.setIndex|setIndex} that builds + * a function that creates a copy of an array-like object with the given * index changed to the desired value.
* If the index is not an integer or if it's out of bounds, the function * will return a copy of the original array.
@@ -593,7 +594,7 @@ function updatePath (path, updater, separator) { * {value: 6, year: "2002"} * ]}; * - * var newUser = _.updatePathIn(user, "scores.0.value", increment); + * var newUser = _.updatePathIn(user, "scores.0.value", inc); * // "newUser" holds: * // {id: 1, scores: [ * // {value: 3, year: "2000"}, diff --git a/src/array.js b/src/array.js index 98e871d..5f7816f 100644 --- a/src/array.js +++ b/src/array.js @@ -54,6 +54,8 @@ function appendTo (arrayLike, value) { * * @memberof module:lamb * @category Array + * @see {@link module:lamb.intersection|intersection} + * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy} * @since 0.6.0 * @param {ArrayLike} arrayLike * @param {ArrayLike} other @@ -300,6 +302,8 @@ var insertAt = _makePartial3(insert); * * @memberof module:lamb * @category Array + * @see {@link module:lamb.difference|difference} + * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy} * @since 0.5.0 * @param {...ArrayLike} arrayLike * @returns {Array} @@ -660,6 +664,8 @@ function transpose (arrayLike) { * @category Array * @function * @see {@link module:lamb.unionBy|unionBy} + * @see {@link module:lamb.difference|difference} + * @see {@link module:lamb.intersection|intersection} * @since 0.5.0 * @param {...ArrayLike} arrayLike * @returns {Array} @@ -682,6 +688,8 @@ var union = unionBy(identity); * @memberof module:lamb * @category Array * @see {@link module:lamb.union|union} + * @see {@link module:lamb.difference|difference} + * @see {@link module:lamb.intersection|intersection} * @since 0.51.0 * @param {ListIteratorCallback} iteratee * @returns {Function} diff --git a/src/object.js b/src/object.js index a517e04..efd3640 100644 --- a/src/object.js +++ b/src/object.js @@ -190,7 +190,7 @@ function mapValues (source, fn) { * @see {@link module:lamb.mapValues|mapValues} * @since 0.54.0 * @function - * @param {Function} fn + * @param {ObjectIteratorCallback} fn * @returns {Function} */ var mapValuesWith = _curry2(mapValues, true); diff --git a/src/privates.js b/src/privates.js index 6a20114..0791c26 100644 --- a/src/privates.js +++ b/src/privates.js @@ -731,6 +731,7 @@ var _search = generic(_stringProto.search); /** * Sets, or creates, a property in a copy of the provided object to the desired value. + * @private * @param {Object} source * @param {String} key * @param {*} value