From 27d393ab624d2d30e720b11f75b3bfeb7b45262f Mon Sep 17 00:00:00 2001 From: Andrea Scartabelli Date: Tue, 19 Apr 2016 14:42:10 +0200 Subject: [PATCH] version bump to 0.22.0 --- README.md | 8 ++- dist/lamb.js | 123 +++++++++++++++++++++++++++++++++++----- dist/lamb.min.js | 4 +- dist/lamb.min.js.map | 2 +- package.json | 2 +- src/logic.js | 2 +- src/object.js | 2 +- test/spec/arraySpec.js | 4 +- test/spec/logicSpec.js | 2 +- test/spec/objectSpec.js | 12 ++-- 10 files changed, 130 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 56b66af..a84fc58 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Lamb it's also delivered on a CDN, courtesy of [npmcdn](https://npmcdn.com/): The URL above will retrieve the latest version, but you can target a specific version too: ```html - + ``` You can [try it right now](https://tonicdev.com/npm/lamb) in your browser, too. @@ -87,9 +87,13 @@ You can refer to the [changelog](#changelog) to see if your code is affected. ## Changelog +- **v0.22.0 - *2016/04/19*** + - **Fully compatible with versions down to 0.21.x** + - Added `updateIn`, `updateKey` and `updateAt` + - **v0.21.0 - *2016/04/13*** - **API change**: `getPathIn` and `getPath` now return `undefined` for any non existent path, instead of throwing exceptions when an `undefined` value was a part of the path instead of being its target - - **API CHANGE**: renamed `sequence` to `generate` to avoid confusion with other languages, concepts and libraries + - **API change**: renamed `sequence` to `generate` to avoid confusion with other languages, concepts and libraries - Added `count`, `countBy`, `index`, `indexBy` - **v0.20.0 - *2016/04/08*** diff --git a/dist/lamb.js b/dist/lamb.js index 964b5cd..e9a9d5b 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.21.0 + * @version 0.22.0 * @module lamb * @license MIT * @preserve @@ -18,7 +18,7 @@ * @category Core * @type String */ - lamb._version = "0.21.0"; + lamb._version = "0.22.0"; // alias used as a placeholder argument for partial application var _ = lamb; @@ -315,6 +315,10 @@ return output; } + function _getPositiveIndex (index, len) { + return clamp(index, -len, len - 1) === Math.floor(index) ? index < 0 ? index + len : index : void 0; + } + function _groupWith (makeValue, startValue) { return function (arrayLike, iteratee, iterateeContext) { return reduce(arrayLike, function (result, element, idx) { @@ -328,6 +332,17 @@ }; } + function _setIndex (arrayLike, index, value, updater) { + var result = slice(arrayLike); + var idx = _getPositiveIndex(index, arrayLike.length); + + if (!isUndefined(idx)) { + result[idx] = updater ? updater(arrayLike[idx]) : value; + } + + return result; + } + /** * Builds a predicate to check if an array-like object contains the given value.
* Please note that the equality test is made with {@link module:lamb.isSVZ|isSVZ}; so you can @@ -668,7 +683,8 @@ */ function getAt (index) { return function (arrayLike) { - return Math.floor(index) === index ? arrayLike[index < 0 ? index + arrayLike.length : index] : void 0; + var idx = _getPositiveIndex(index, arrayLike.length); + return isUndefined(idx) ? idx : arrayLike[idx]; }; } @@ -1161,14 +1177,7 @@ */ function setAt (index, value) { return function (arrayLike) { - var result = slice(arrayLike); - var len = arrayLike.length; - - if (clamp(index, -len, len - 1) === Math.floor(index)) { - result[index + (index < 0 ? len : 0)] = value; - } - - return result; + return _setIndex(arrayLike, index, value); }; } @@ -1376,6 +1385,31 @@ return result; } + /** + * Builds a function that creates a copy of an array-like object with the given index changed + * by applying the provided function to its 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.
+ * Negative indexes are allowed. + * @example + * var arr = ["a", "b", "c"]; + * var toUpperCase = _.invoker("toUpperCase"); + * + * _.updateAt(1, toUpperCase)(arr) // => ["a", "B", "c"] + * _.updateAt(-1, toUpperCase)(arr) // => ["a", "b", "C"] + * _.updateAt(10, toUpperCase)(arr) // => ["a", "b", "c"] + * + * @memberof module:lamb + * @category Array + * @param {Number} index + * @param {Function} updater + * @returns {Function} + */ + function updateAt (index, updater) { + return function (arrayLike) { + return _setIndex(arrayLike, index, null, updater); + }; + } + /** * Builds a list of arrays out of the given array-like objects by pairing items with the same index.
* The received array-like objects will be truncated to the shortest length.
@@ -1449,6 +1483,7 @@ lamb.transpose = transpose; lamb.union = union; lamb.uniques = uniques; + lamb.updateAt = updateAt; lamb.zip = zip; lamb.zipWithIndex = zipWithIndex; @@ -2253,7 +2288,7 @@ /** * Accepts a series of functions and builds a function that applies the received arguments to each one and - * returns the first non undefined value.
+ * returns the first non-undefined value.
* Meant to work in sinergy with {@link module:lamb.condition|condition} and {@link module:lamb.invoker|invoker}, * can be useful as a strategy pattern for functions, to mimic conditional logic and also to build polymorphic functions. * @example @@ -2808,6 +2843,10 @@ return obj; } + function _isEnumerable (obj, key) { + return key in Object(obj) && isIn(enumerables(obj), key); + } + function _keyToPair (key) { return [key, this[key]]; } @@ -3407,12 +3446,14 @@ * var user = {name: "John", surname: "Doe", age: 30}; * * _.setIn(user, "name", "Jane") // => {name: "Jane", surname: "Doe", age: 30} + * _.setIn(user, "gender", "male") // => {name: "John", surname: "Doe", age: 30, gender: "male"} * * // `user` still is {name: "John", surname: "Doe", age: 30} * * @memberof module:lamb * @category Object * @see {@link module:lamb.setKey|setKey} + * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn} * @param {Object} source * @param {String} key * @param {*} value @@ -3473,7 +3514,7 @@ /** * Allows to change a nested value in a copy of the provided object.
- * The function will delegate the "set" action to {@link module:lamb.setIn|setIn} or + * The function will delegate the "set action" to {@link module:lamb.setIn|setIn} or * {@link module:lamb.setAt|setAt} depending on the value encountered in the path, * so please refer to the documentation of those functions for specifics about the * implementation.
@@ -3481,7 +3522,7 @@ * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects), * which will be delegated to {@link module:lamb.setIn|setIn}.
* As a result of that, array-like objects will be converted to objects having numbers as keys - * and paths targeting non object values will be converted to empty objects.
+ * and paths targeting non-object values will be converted to empty objects.
* Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can * use custom path separators. * @example @@ -3608,6 +3649,58 @@ */ var tearOwn = _tearFrom(Object.keys); + /** + * Creates a copy of the given object having the desired key value updated by applying + * the provided function to it.
+ * This function is meant for updating existing enumerable properties, and for those it + * will delegate the "set action" to {@link module:lamb.setIn|setIn}; a copy of the + * source is returned otherwise. + * @example + * var user = {name: "John", visits: 2}; + * var toUpperCase = _.invoker("toUpperCase"); + * + * _.updateIn(user, "name", toUpperCase) // => {name: "JOHN", visits: 2} + * _.updateIn(user, "surname", toUpperCase) // => {name: "John", visits: 2} + * + * @example Non-enumerable properties will be treated as non-existent: + * var user = Object.create({name: "John"}, {visits: {value: 2}}); + * var increment = _.partial(_.add, 1); + * + * _.updateIn(user, "visits", increment) // => {name: "John", visits: 2} + * + * @memberof module:lamb + * @category Object + * @see {@link module:lamb.updateKey|updateKey} + * @param {Object} source + * @param {String} key + * @param {Function} updater + * @returns {Object} + */ + function updateIn (source, key, updater) { + return _isEnumerable(source, key) ? setIn(source, key, updater(source[key])) : _merge(enumerables, source); + } + + /** + * Builds a partial application of {@link module:lamb.updateIn|updateIn} with the provided + * key and updater, expecting the object to act upon. + * @example + * var user = {name: "John", visits: 2}; + * var increment = _.partial(_.add, 1); + * var incrementVisits = _.updateKey("visits", increment); + * + * incrementVisits(user) // => {name: "John", visits: 3} + * + * @memberof module:lamb + * @category Object + * @see {@link module:lamb.updateIn|updateIn} + * @param {String} key + * @param {Function} updater + * @returns {Function} + */ + function updateKey (key, updater) { + return partial(updateIn, _, key, updater); + } + /** * Validates an object with the given list of {@link module:lamb.checker|checker} functions. * @example @@ -3715,6 +3808,8 @@ lamb.skipIf = skipIf; lamb.tear = tear; lamb.tearOwn = tearOwn; + lamb.updateIn = updateIn; + lamb.updateKey = updateKey; lamb.validate = validate; lamb.validateWith = validateWith; lamb.values = values; diff --git a/dist/lamb.min.js b/dist/lamb.min.js index 403b96a..f9c7960 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.21.0 + * @version 0.22.0 * @module lamb * @license MIT * @preserve */ -!function(n){"use strict";function r(n){return function(){return n}}function t(){var n=arguments;return function(){for(var r=arguments,t=n.length;t--;)r=[n[t].apply(this,r)];return r[0]}}function e(n){return n}function u(n){var r=gr(arguments,1);return function(){for(var t,e=0,u=[],i=r.length,o=0;i>o;o++)t=r[o],u[o]=t===cr?arguments[e++]:t;for(var c=arguments.length;c>e;e++)u.push(arguments[e]);return n.apply(this,u)}}function i(n,r,t){for(var e=-1,u=n.length;++ei;i++)if(u=n[i],r.call(t,u,i,n)){e=u;break}return e}function v(n,r,t){for(var e=-1,u=0,i=n.length;i>u;u++)if(r.call(t,n[u],u,n)){e=u;break}return e}function y(n,r){return u(kr,cr,n,r)}function d(n){return o(n,[])}function g(n){return function(r){return Math.floor(n)===n?r[0>n?n+r.length:n]:void 0}}function m(n,r){return u(xr,cr,n,r)}function b(n,r){return u(wr,cr,n,r)}function O(){var n=gr(arguments,1);return N(arguments[0]).filter(function(r){return n.every(f(r))})}function k(n,r,t){for(var e=!1,u=t>>>0,i=n.length;i>u;u++)if(gn(r,n[u])){e=!0;break}return e}function x(){return 1===arguments.length?[arguments[0]]:Array.apply(null,arguments)}function j(n,r){return u(vr,cr,n,r)}function w(n,r,t){for(var e,u=[[],[]],i=n.length,o=0;i>o;o++)e=n[o],u[r.call(t,e,o,n)?0:1].push(e);return u}function A(n,r){return u(w,cr,n,r)}function I(n,r){return vr(n,Gr(r))}function M(n){return j(Gr(n))}function W(n){return gr(n).reverse()}function E(n,r){return function(t){var e=gr(t),u=t.length;return On(n,-u,u-1)===Math.floor(n)&&(e[n+(0>n?u:0)]=r),e}}function P(n){return fr.concat.apply([],n)}function T(n,r){return function(t){return gr(t,0,i(t,n,r))}}function K(n){for(var r,t=[],e=Z(Math.min,I(n,"length"))>>>0,u=n.length,i=0;e>i;i++)for(t.push([]),r=0;u>r;r++)t[i][r]=n[r][i];return t}function N(n,r,t){"function"!=typeof r&&(r=e);for(var u,i=[],o=[],c=0;cr||n!==n?t=1:(r>n||r!==r)&&(t=-1)),t}function D(n){var r=n.length;return function(t,e){for(var u,i,o=0,c=0;r>c;c++)if(i=n[c],o=i.compare(t.value,e.value),0!==o){u=n[c].isDescending;break}return 0===o&&(u=n[r-1].isDescending,o=t.index-e.index),u?-o:o}}function F(n,r,t,e,u){if(0===n.length)return 0;var i=e+u>>1,o=t({value:r,index:i},{value:n[i],index:i});return 1>=u-e?0>o?i:i+1:0>o?F(n,r,t,e,i):0===o?i+1:F(n,r,t,i,u)}function z(n){return n.length?n.map(S):[B()]}function S(n){return"function"==typeof Object(n).compare?n:B(n)}function B(n,r,t){return{isDescending:r===!0,compare:function(r,u){return"function"==typeof n&&n!==e&&(r=n(r),u=n(u)),(t||R)(r,u)}}}function L(n,r){var t=z(gr(arguments,2)),e=n.concat(),u=F(n,r,D(t),0,n.length);return e.splice(u,0,r),e}function V(n){for(var r=z(gr(arguments,1)),t=[],e=[],u=n.length,i=0;u>i;i++)t.push({value:n[i],index:i});for(t.sort(D(r)),i=0;u>i;i++)e.push(t[i].value);return e}function G(){var n=gr(arguments);return function(r){return V.apply(null,[r].concat(n))}}function q(n,r,t,e,u){return function(){var i=u.concat(e(arguments));return i.length>=r?n.apply(this,t?i.reverse():i):q(n,r,t,e,i)}}function U(n,r,t,e){var u=e?gr:function(n){return n.length?[n[0]]:[]};return r>>>0!==r&&(r=n.length),q(n,r,t,u,[])}function Z(n,r){return n.apply(n,gr(r))}function $(n,r){return function(){return Z(n,gr(arguments,0,r))}}function _(n){return function(r,t){return n(r,t)}}function C(n,r){return U(n,r,!1)}function H(n,r){return U(n,r,!0)}function J(n,r){return U(n,r,!1,!0)}function Q(n,r){return U(n,r,!0,!0)}function X(n,r){var t;return function(){var e=this,u=arguments,i=function(){t=null,n.apply(e,u)};clearTimeout(t),t=setTimeout(i,r)}}function Y(n){return function(){var r=gr(arguments).reverse();return n.apply(this,r)}}function nn(n){return t(g(n),x)}function rn(n){return function(r){var t=gr(arguments,1),e=n[r];return"Function"===ir(e)?e.apply(n,t):void 0}}function tn(n){var r=gr(arguments,1);return function(t){var e=gr(arguments,1),u=t[n];return"Function"===ir(u)?u.apply(t,r.concat(e)):void 0}}function en(n,r){return t(u(Z,n),j(r),x)}function un(n){var r=gr(arguments,1);return function(){for(var t=arguments.length,e=[],u=0;t>u;u++)e.push(r[u]?r[u](arguments[u]):arguments[u]);return n.apply(this,e)}}function on(n,r){var t,e=0;return function(){var u=Date.now();return u-e>=r&&(e=u,t=n.apply(this,arguments)),t}}function cn(n){return function(r){return n(r)}}function fn(){var n=gr(arguments);return function(){for(var r,t=n.length,e=0;t>e&&(r=Z(n[e],arguments),ur(r));e++);return r}}function an(){var n=gr(arguments);return function(){var r=arguments;return n.every(function(n){return n.apply(null,r)})}}function ln(){var n=gr(arguments);return function(){var r=arguments;return n.some(function(n){return n.apply(null,r)})}}function pn(n,r,t){return function(){var e=Dr(arguments);return e(n)?e(r):t?e(t):void 0}}function sn(n,r){return 0===n&&0===r?1/n===1/r:gn(n,r)}function hn(n,r){return n>r}function vn(n,r){return n>=r}function yn(n,r){return r>n}function dn(n,r){return r>=n}function gn(n,r){return n!==n?r!==r:n===r}function mn(n){return function(){return!n.apply(null,arguments)}}function bn(n,r){return n+r}function On(n,r,t){return r>n?r:n>t?t:n}function kn(n,r){return n/r}function xn(n,r,t,e){for(var u=[n],i=0,o=r-1;o>i;i++)u.push(t.call(e,u[i],i,u));return u}function jn(n,r){return n-r*Math.floor(n/r)}function wn(n,r){return n*r}function An(n,r){return Math.floor(Math.random()*(r-n+1)+n)}function In(n,r,t){if(0===t||arguments.length<2)return[n];t||(t=1);var e=Math.max(Math.ceil((r-n)/t),0);return xn(n,e,u(bn,t))}function Mn(n,r){return n%r}function Wn(n,r){return n-r}function En(n,r){return-1===r.indexOf(n)&&(r.push(Object.freeze(n)),Object.getOwnPropertyNames(n).forEach(function(t){var e=n[t];"object"!=typeof e||tr(e)||En(e,r)})),n}function Pn(n){return[n,this[n]]}function Tn(n){return yr(gr(arguments,1),function(r,t){return hr(n(t),function(n){r[n]=t[n]}),r},{})}function Kn(n,r,t){var e,i,o=parseInt(r[0],10);return Array.isArray(n)&&o==r[0]?(e=g(o)(n),i=function(r){return E(o,r)(n)}):(e=(n||{})[r[0]],i=u(Un,n,r[0])),i(r.length<2?t:Kn(e,r.slice(1),t))}function Nn(n,r,t,e){return function(i){var o=u(Sn,i,cr,e);return n.apply(i,t.map(o))?[]:[r,t]}}function Rn(n){var r=[];for(var t in n)r.push(t);return r}function Dn(n){var r={};return n.forEach(function(n){r[n[0]]=n[1]}),r}function Fn(n,r){return n[r]}function zn(n,r){return u(Sn,cr,n,r)}function Sn(n,r,t){return r.split(t||".").reduce(un(Fn,Object),n)}function Bn(n,r){return r in n}function Ln(n){return En(n,[])}function Vn(n,r){for(var t={},e=r.length,u=0,i=n.length;i>u;u++)t[n[u]]=e>u?r[u]:void 0;return t}function Gn(n,r){var t={};return r.forEach(function(r){r in n&&(t[r]=n[r])}),t}function qn(n,r){return function(t){var e={};for(var u in t)n.call(r,t[u],u,t)&&(e[u]=t[u]);return e}}function Un(n,r,t){return Tn(Rn,n,Vn([r],[t]))}function Zn(n,r){return u(Un,cr,n,r)}function $n(n,r,t){return u(_n,cr,n,r,t)}function _n(n,r,t,e){return Kn(n,r.split(e||"."),t)}function Cn(n,r){var t={};for(var e in n)-1===r.indexOf(e)&&(t[e]=n[e]);return t}function Hn(n,r){return qn(mn(n),r)}function Jn(n,r){return r.reduce(function(r,t){var e=t(n);return e.length&&r.push(e),r},[])}function Qn(n,r,t){return nr(r[0]||" ",Math.ceil(t-n.length))}function Xn(n,r,t){return Qn(n,r,t)+n}function Yn(n,r,t){return n+Qn(n,r,t)}function nr(n,r){for(var t="",e=0;r>e;e++)t+=n;return t}function rr(n){return lr.test.bind(n)}function tr(n){return null===n}function er(n){return function(r){return ir(r)===n}}function ur(n){return void 0===n}function ir(n){return ar.toString.call(n).replace(/^\[\w+\s+|\]$/g,"")}var or=Object.create(null);or._version="0.21.0";var cr=or,fr=Array.prototype,ar=Object.prototype,lr=RegExp.prototype,pr=Function.bind.bind(Function.call);or.always=r,or.compose=t,or.generic=pr,or.identity=e,or.partial=u;var sr=pr(fr.filter),hr=pr(fr.forEach),vr=pr(fr.map),yr=pr(fr.reduce),dr=pr(fr.reduceRight),gr=pr(fr.slice);or.filter=sr,or.forEach=hr,or.map=vr,or.reduce=yr,or.reduceRight=dr,or.slice=gr;var mr=c(u(bn,1),0),br=_(gr),Or=U(br,2,!0),kr=t(P,vr),xr=c(tn("concat"),[]),jr=g(0),wr=c(nn(1)),Ar=u(gr,cr,0,-1),Ir=g(-1),Mr=u(gr,cr,1,void 0),Wr=u(gr,cr,0,cr),Er=U(Wr,2,!0),Pr=t(N,y(cn(gr)),x),Tr=t(K,x),Kr=j(_(x));or.contains=f,or.count=mr,or.countBy=a,or.difference=l,or.drop=br,or.dropN=Or,or.dropWhile=p,or.filterWith=s,or.find=h,or.findIndex=v,or.flatMap=kr,or.flatMapWith=y,or.flatten=d,or.getAt=g,or.group=xr,or.groupBy=m,or.head=jr,or.index=wr,or.indexBy=b,or.init=Ar,or.intersection=O,or.isIn=k,or.last=Ir,or.list=x,or.mapWith=j,or.partition=w,or.partitionWith=A,or.pluck=I,or.pluckKey=M,or.reverse=W,or.setAt=E,or.shallowFlatten=P,or.tail=Mr,or.take=Wr,or.takeN=Er,or.takeWhile=T,or.transpose=K,or.union=Pr,or.uniques=N,or.zip=Tr,or.zipWithIndex=Kr;var Nr=u(B,cr,!1,cr),Rr=u(B,cr,!0,cr);or.insert=L,or.sort=V,or.sorter=Nr,or.sorterDesc=Rr,or.sortWith=G;var Dr=U(Z,2,!0),Fr=Y(t),zr=_(Y(u));or.apply=Z,or.applyArgs=Dr,or.aritize=$,or.binary=_,or.curry=C,or.curryRight=H,or.curryable=J,or.curryableRight=Q,or.debounce=X,or.flip=Y,or.getArgAt=nn,or.invokerOn=rn,or.invoker=tn,or.mapArgs=en,or.pipe=Fr,or.tapArgs=un,or.throttle=on,or.unary=cn,or.wrap=zr;var Sr=mn(sn);or.adapter=fn,or.allOf=an,or.anyOf=ln,or.condition=pn,or.is=sn,or.isGT=hn,or.isGTE=vn,or.isLT=yn,or.isLTE=dn,or.isNot=Sr,or.isSVZ=gn,or.not=mn,or.add=bn,or.clamp=On,or.divide=kn,or.generate=xn,or.modulo=jn,or.multiply=wn,or.randomInt=An,or.range=In,or.remainder=Mn,or.subtract=Wn;var Br=U(function(n,r){return n(r).map(Pn,r)}),Lr=U(function(n,r){return n(r).reduce(function(n,t){return n[0].push(t),n[1].push(r[t]),n},[[],[]])}),Vr=U(function(n,r){return n(r).map(u(Fn,r))}),Gr=U(Fn,2,!0),qr=U(Bn,2,!0),Ur=function(n,r){return t(u(sn,r),Gr(n))},Zr=pr(ar.hasOwnProperty),$r=U(Zr,2,!0),_r=u(Tn,Rn),Cr=u(Tn,t(Object.keys,Object)),Hr=Br(Object.keys),Jr=Vr(Object.keys),Qr=Br(Rn),Xr=Lr(Rn),Yr=Lr(Object.keys),nt=U(Jn,2,!0),rt=Vr(Rn);or.checker=Nn,or.enumerables=Rn,or.fromPairs=Dn,or.getIn=Fn,or.getKey=Gr,or.getPath=zn,or.getPathIn=Sn,or.has=Bn,or.hasKey=qr,or.hasKeyValue=Ur,or.hasOwn=Zr,or.hasOwnKey=$r,or.immutable=Ln,or.make=Vn,or.merge=_r,or.mergeOwn=Cr,or.ownPairs=Hr,or.ownValues=Jr,or.pairs=Qr,or.pick=Gn,or.pickIf=qn,or.setIn=Un,or.setKey=Zn,or.setPath=$n,or.setPathIn=_n,or.skip=Cn,or.skipIf=Hn,or.tear=Xr,or.tearOwn=Yr,or.validate=Jn,or.validateWith=nt,or.values=rt,or.padLeft=Xn,or.padRight=Yn,or.repeat=nr,or.testWith=rr;var tt=ln(tr,ur);or.isNil=tt,or.isNull=tr,or.isType=er,or.isUndefined=ur,or.type=ir,"object"==typeof exports?module.exports=or:"function"==typeof define&&define.amd?define(function(){return or}):n.lamb=or}(this); +!function(n){"use strict";function r(n){return function(){return n}}function t(){var n=arguments;return function(){for(var r=arguments,t=n.length;t--;)r=[n[t].apply(this,r)];return r[0]}}function e(n){return n}function u(n){var r=jr(arguments,1);return function(){for(var t,e=0,u=[],i=r.length,o=0;i>o;o++)t=r[o],u[o]=t===hr?arguments[e++]:t;for(var c=arguments.length;c>e;e++)u.push(arguments[e]);return n.apply(this,u)}}function i(n,r,t){for(var e=-1,u=n.length;++en?n+r:n:void 0}function f(n,r){return function(t,e,u){return kr(t,function(i,o,c){var f=e.call(u,o,c,t),a=n(f in i?i[f]:r,o);return i[f]=a,i},{})}}function a(n,r,t,e){var u=jr(n),i=c(r,n.length);return lr(i)||(u[i]=e?e(n[i]):t),u}function l(n,r){return function(t){return j(t,n,r)}}function p(n,r){return u(Ar,hr,n,r)}function s(n){var r=T(jr(arguments,1)),t=u(j,r,hr,0);return n.filter(kn(t))}function h(n,r){return function(t){return jr(t,i(t,n,r))}}function v(n,r){return u(mr,hr,n,r)}function y(n,r,t){for(var e,u,i=0,o=n.length;o>i;i++)if(u=n[i],r.call(t,u,i,n)){e=u;break}return e}function d(n,r,t){for(var e=-1,u=0,i=n.length;i>u;u++)if(r.call(t,n[u],u,n)){e=u;break}return e}function g(n,r){return u(Mr,hr,n,r)}function m(n){return o(n,[])}function b(n){return function(r){var t=c(n,r.length);return lr(t)?t:r[t]}}function O(n,r){return u(Wr,hr,n,r)}function k(n,r){return u(Pr,hr,n,r)}function x(){var n=jr(arguments,1);return D(arguments[0]).filter(function(r){return n.every(l(r))})}function j(n,r,t){for(var e=!1,u=t>>>0,i=n.length;i>u;u++)if(On(r,n[u])){e=!0;break}return e}function A(){return 1===arguments.length?[arguments[0]]:Array.apply(null,arguments)}function w(n,r){return u(Or,hr,n,r)}function I(n,r,t){for(var e,u=[[],[]],i=n.length,o=0;i>o;o++)e=n[o],u[r.call(t,e,o,n)?0:1].push(e);return u}function M(n,r){return u(I,hr,n,r)}function W(n,r){return Or(n,Cr(r))}function E(n){return w(Cr(n))}function P(n){return jr(n).reverse()}function K(n,r){return function(t){return a(t,n,r)}}function T(n){return vr.concat.apply([],n)}function N(n,r){return function(t){return jr(t,0,i(t,n,r))}}function R(n){for(var r,t=[],e=C(Math.min,W(n,"length"))>>>0,u=n.length,i=0;e>i;i++)for(t.push([]),r=0;u>r;r++)t[i][r]=n[r][i];return t}function D(n,r,t){"function"!=typeof r&&(r=e);for(var u,i=[],o=[],c=0;cr||n!==n?t=1:(r>n||r!==r)&&(t=-1)),t}function S(n){var r=n.length;return function(t,e){for(var u,i,o=0,c=0;r>c;c++)if(i=n[c],o=i.compare(t.value,e.value),0!==o){u=n[c].isDescending;break}return 0===o&&(u=n[r-1].isDescending,o=t.index-e.index),u?-o:o}}function B(n,r,t,e,u){if(0===n.length)return 0;var i=e+u>>1,o=t({value:r,index:i},{value:n[i],index:i});return 1>=u-e?0>o?i:i+1:0>o?B(n,r,t,e,i):0===o?i+1:B(n,r,t,i,u)}function L(n){return n.length?n.map(V):[G()]}function V(n){return"function"==typeof Object(n).compare?n:G(n)}function G(n,r,t){return{isDescending:r===!0,compare:function(r,u){return"function"==typeof n&&n!==e&&(r=n(r),u=n(u)),(t||z)(r,u)}}}function q(n,r){var t=L(jr(arguments,2)),e=n.concat(),u=B(n,r,S(t),0,n.length);return e.splice(u,0,r),e}function U(n){for(var r=L(jr(arguments,1)),t=[],e=[],u=n.length,i=0;u>i;i++)t.push({value:n[i],index:i});for(t.sort(S(r)),i=0;u>i;i++)e.push(t[i].value);return e}function Z(){var n=jr(arguments);return function(r){return U.apply(null,[r].concat(n))}}function $(n,r,t,e,u){return function(){var i=u.concat(e(arguments));return i.length>=r?n.apply(this,t?i.reverse():i):$(n,r,t,e,i)}}function _(n,r,t,e){var u=e?jr:function(n){return n.length?[n[0]]:[]};return r>>>0!==r&&(r=n.length),$(n,r,t,u,[])}function C(n,r){return n.apply(n,jr(r))}function H(n,r){return function(){return C(n,jr(arguments,0,r))}}function J(n){return function(r,t){return n(r,t)}}function Q(n,r){return _(n,r,!1)}function X(n,r){return _(n,r,!0)}function Y(n,r){return _(n,r,!1,!0)}function nn(n,r){return _(n,r,!0,!0)}function rn(n,r){var t;return function(){var e=this,u=arguments,i=function(){t=null,n.apply(e,u)};clearTimeout(t),t=setTimeout(i,r)}}function tn(n){return function(){var r=jr(arguments).reverse();return n.apply(this,r)}}function en(n){return t(b(n),A)}function un(n){return function(r){var t=jr(arguments,1),e=n[r];return"Function"===pr(e)?e.apply(n,t):void 0}}function on(n){var r=jr(arguments,1);return function(t){var e=jr(arguments,1),u=t[n];return"Function"===pr(u)?u.apply(t,r.concat(e)):void 0}}function cn(n,r){return t(u(C,n),w(r),A)}function fn(n){var r=jr(arguments,1);return function(){for(var t=arguments.length,e=[],u=0;t>u;u++)e.push(r[u]?r[u](arguments[u]):arguments[u]);return n.apply(this,e)}}function an(n,r){var t,e=0;return function(){var u=Date.now();return u-e>=r&&(e=u,t=n.apply(this,arguments)),t}}function ln(n){return function(r){return n(r)}}function pn(){var n=jr(arguments);return function(){for(var r,t=n.length,e=0;t>e&&(r=C(n[e],arguments),lr(r));e++);return r}}function sn(){var n=jr(arguments);return function(){var r=arguments;return n.every(function(n){return n.apply(null,r)})}}function hn(){var n=jr(arguments);return function(){var r=arguments;return n.some(function(n){return n.apply(null,r)})}}function vn(n,r,t){return function(){var e=Vr(arguments);return e(n)?e(r):t?e(t):void 0}}function yn(n,r){return 0===n&&0===r?1/n===1/r:On(n,r)}function dn(n,r){return n>r}function gn(n,r){return n>=r}function mn(n,r){return r>n}function bn(n,r){return r>=n}function On(n,r){return n!==n?r!==r:n===r}function kn(n){return function(){return!n.apply(null,arguments)}}function xn(n,r){return n+r}function jn(n,r,t){return r>n?r:n>t?t:n}function An(n,r){return n/r}function wn(n,r,t,e){for(var u=[n],i=0,o=r-1;o>i;i++)u.push(t.call(e,u[i],i,u));return u}function In(n,r){return n-r*Math.floor(n/r)}function Mn(n,r){return n*r}function Wn(n,r){return Math.floor(Math.random()*(r-n+1)+n)}function En(n,r,t){if(0===t||arguments.length<2)return[n];t||(t=1);var e=Math.max(Math.ceil((r-n)/t),0);return wn(n,e,u(xn,t))}function Pn(n,r){return n%r}function Kn(n,r){return n-r}function Tn(n,r){return-1===r.indexOf(n)&&(r.push(Object.freeze(n)),Object.getOwnPropertyNames(n).forEach(function(t){var e=n[t];"object"!=typeof e||fr(e)||Tn(e,r)})),n}function Nn(n,r){return r in Object(n)&&j(Sn(n),r)}function Rn(n){return[n,this[n]]}function Dn(n){return kr(jr(arguments,1),function(r,t){return br(n(t),function(n){r[n]=t[n]}),r},{})}function Fn(n,r,t){var e,i,o=parseInt(r[0],10);return Array.isArray(n)&&o==r[0]?(e=b(o)(n),i=function(r){return K(o,r)(n)}):(e=(n||{})[r[0]],i=u(Cn,n,r[0])),i(r.length<2?t:Fn(e,r.slice(1),t))}function zn(n,r,t,e){return function(i){var o=u(Gn,i,hr,e);return n.apply(i,t.map(o))?[]:[r,t]}}function Sn(n){var r=[];for(var t in n)r.push(t);return r}function Bn(n){var r={};return n.forEach(function(n){r[n[0]]=n[1]}),r}function Ln(n,r){return n[r]}function Vn(n,r){return u(Gn,hr,n,r)}function Gn(n,r,t){return r.split(t||".").reduce(fn(Ln,Object),n)}function qn(n,r){return r in n}function Un(n){return Tn(n,[])}function Zn(n,r){for(var t={},e=r.length,u=0,i=n.length;i>u;u++)t[n[u]]=e>u?r[u]:void 0;return t}function $n(n,r){var t={};return r.forEach(function(r){r in n&&(t[r]=n[r])}),t}function _n(n,r){return function(t){var e={};for(var u in t)n.call(r,t[u],u,t)&&(e[u]=t[u]);return e}}function Cn(n,r,t){return Dn(Sn,n,Zn([r],[t]))}function Hn(n,r){return u(Cn,hr,n,r)}function Jn(n,r,t){return u(Qn,hr,n,r,t)}function Qn(n,r,t,e){return Fn(n,r.split(e||"."),t)}function Xn(n,r){var t={};for(var e in n)-1===r.indexOf(e)&&(t[e]=n[e]);return t}function Yn(n,r){return _n(kn(n),r)}function nr(n,r,t){return Nn(n,r)?Cn(n,r,t(n[r])):Dn(Sn,n)}function rr(n,r){return u(nr,hr,n,r)}function tr(n,r){return r.reduce(function(r,t){var e=t(n);return e.length&&r.push(e),r},[])}function er(n,r,t){return or(r[0]||" ",Math.ceil(t-n.length))}function ur(n,r,t){return er(n,r,t)+n}function ir(n,r,t){return n+er(n,r,t)}function or(n,r){for(var t="",e=0;r>e;e++)t+=n;return t}function cr(n){return dr.test.bind(n)}function fr(n){return null===n}function ar(n){return function(r){return pr(r)===n}}function lr(n){return void 0===n}function pr(n){return yr.toString.call(n).replace(/^\[\w+\s+|\]$/g,"")}var sr=Object.create(null);sr._version="0.22.0";var hr=sr,vr=Array.prototype,yr=Object.prototype,dr=RegExp.prototype,gr=Function.bind.bind(Function.call);sr.always=r,sr.compose=t,sr.generic=gr,sr.identity=e,sr.partial=u;var mr=gr(vr.filter),br=gr(vr.forEach),Or=gr(vr.map),kr=gr(vr.reduce),xr=gr(vr.reduceRight),jr=gr(vr.slice);sr.filter=mr,sr.forEach=br,sr.map=Or,sr.reduce=kr,sr.reduceRight=xr,sr.slice=jr;var Ar=f(u(xn,1),0),wr=J(jr),Ir=_(wr,2,!0),Mr=t(T,Or),Wr=f(on("concat"),[]),Er=b(0),Pr=f(en(1)),Kr=u(jr,hr,0,-1),Tr=b(-1),Nr=u(jr,hr,1,void 0),Rr=u(jr,hr,0,hr),Dr=_(Rr,2,!0),Fr=t(D,g(ln(jr)),A),zr=t(R,A),Sr=w(J(A));sr.contains=l,sr.count=Ar,sr.countBy=p,sr.difference=s,sr.drop=wr,sr.dropN=Ir,sr.dropWhile=h,sr.filterWith=v,sr.find=y,sr.findIndex=d,sr.flatMap=Mr,sr.flatMapWith=g,sr.flatten=m,sr.getAt=b,sr.group=Wr,sr.groupBy=O,sr.head=Er,sr.index=Pr,sr.indexBy=k,sr.init=Kr,sr.intersection=x,sr.isIn=j,sr.last=Tr,sr.list=A,sr.mapWith=w,sr.partition=I,sr.partitionWith=M,sr.pluck=W,sr.pluckKey=E,sr.reverse=P,sr.setAt=K,sr.shallowFlatten=T,sr.tail=Nr,sr.take=Rr,sr.takeN=Dr,sr.takeWhile=N,sr.transpose=R,sr.union=Fr,sr.uniques=D,sr.updateAt=F,sr.zip=zr,sr.zipWithIndex=Sr;var Br=u(G,hr,!1,hr),Lr=u(G,hr,!0,hr);sr.insert=q,sr.sort=U,sr.sorter=Br,sr.sorterDesc=Lr,sr.sortWith=Z;var Vr=_(C,2,!0),Gr=tn(t),qr=J(tn(u));sr.apply=C,sr.applyArgs=Vr,sr.aritize=H,sr.binary=J,sr.curry=Q,sr.curryRight=X,sr.curryable=Y,sr.curryableRight=nn,sr.debounce=rn,sr.flip=tn,sr.getArgAt=en,sr.invokerOn=un,sr.invoker=on,sr.mapArgs=cn,sr.pipe=Gr,sr.tapArgs=fn,sr.throttle=an,sr.unary=ln,sr.wrap=qr;var Ur=kn(yn);sr.adapter=pn,sr.allOf=sn,sr.anyOf=hn,sr.condition=vn,sr.is=yn,sr.isGT=dn,sr.isGTE=gn,sr.isLT=mn,sr.isLTE=bn,sr.isNot=Ur,sr.isSVZ=On,sr.not=kn,sr.add=xn,sr.clamp=jn,sr.divide=An,sr.generate=wn,sr.modulo=In,sr.multiply=Mn,sr.randomInt=Wn,sr.range=En,sr.remainder=Pn,sr.subtract=Kn;var Zr=_(function(n,r){return n(r).map(Rn,r)}),$r=_(function(n,r){return n(r).reduce(function(n,t){return n[0].push(t),n[1].push(r[t]),n},[[],[]])}),_r=_(function(n,r){return n(r).map(u(Ln,r))}),Cr=_(Ln,2,!0),Hr=_(qn,2,!0),Jr=function(n,r){return t(u(yn,r),Cr(n))},Qr=gr(yr.hasOwnProperty),Xr=_(Qr,2,!0),Yr=u(Dn,Sn),nt=u(Dn,t(Object.keys,Object)),rt=Zr(Object.keys),tt=_r(Object.keys),et=Zr(Sn),ut=$r(Sn),it=$r(Object.keys),ot=_(tr,2,!0),ct=_r(Sn);sr.checker=zn,sr.enumerables=Sn,sr.fromPairs=Bn,sr.getIn=Ln,sr.getKey=Cr,sr.getPath=Vn,sr.getPathIn=Gn,sr.has=qn,sr.hasKey=Hr,sr.hasKeyValue=Jr,sr.hasOwn=Qr,sr.hasOwnKey=Xr,sr.immutable=Un,sr.make=Zn,sr.merge=Yr,sr.mergeOwn=nt,sr.ownPairs=rt,sr.ownValues=tt,sr.pairs=et,sr.pick=$n,sr.pickIf=_n,sr.setIn=Cn,sr.setKey=Hn,sr.setPath=Jn,sr.setPathIn=Qn,sr.skip=Xn,sr.skipIf=Yn,sr.tear=ut,sr.tearOwn=it,sr.updateIn=nr,sr.updateKey=rr,sr.validate=tr,sr.validateWith=ot,sr.values=ct,sr.padLeft=ur,sr.padRight=ir,sr.repeat=or,sr.testWith=cr;var ft=hn(fr,lr);sr.isNil=ft,sr.isNull=fr,sr.isType=ar,sr.isUndefined=lr,sr.type=pr,"object"==typeof exports?module.exports=sr:"function"==typeof define&&define.amd?define(function(){return sr}):n.lamb=sr}(this); //# sourceMappingURL=lamb.min.js.map diff --git a/dist/lamb.min.js.map b/dist/lamb.min.js.map index 9ba331c..5ea8985 100644 --- a/dist/lamb.min.js.map +++ b/dist/lamb.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["lamb.js"],"names":["host","always","value","compose","functions","arguments","args","len","length","apply","this","identity","partial","fn","slice","boundArg","lastArgumentIdx","newArgs","argsLen","i","_","push","_findSliceEndIndex","arrayLike","predicate","predicateContext","idx","call","_flatten","array","output","forEach","Array","isArray","_groupWith","makeValue","startValue","iteratee","iterateeContext","reduce","result","element","key","contains","fromIndex","isIn","countBy","count","difference","rest","shallowFlatten","isInRest","filter","not","dropWhile","filterWith","find","findIndex","flatMapWith","flatMap","flatten","getAt","index","Math","floor","groupBy","group","indexBy","intersection","uniques","item","every","isSVZ","list","mapWith","map","partition","el","partitionWith","pluck","getKey","pluckKey","reverse","setAt","clamp","_arrayProto","concat","takeWhile","transpose","j","minLen","min","seen","_comparer","a","b","String","_compareWith","criteria","isDescSort","criterion","compare","isDescending","_getInsertionIndex","comparer","start","end","pivot","_makeCriteria","sorters","_makeCriterion","_sorter","Object","reader","insert","splice","sort","data","sortWith","_currier","arity","isRightCurry","slicer","argsHolder","_curry","isAutoCurry","aritize","binary","curry","curryRight","curryable","curryableRight","debounce","timespan","timeoutID","context","debounced","clearTimeout","setTimeout","flip","getArgAt","invokerOn","target","methodName","method","type","invoker","boundArgs","mapArgs","mapper","tapArgs","readers","throttle","lastCall","now","Date","unary","adapter","isUndefined","allOf","predicates","anyOf","some","condition","trueFn","falseFn","applyArgsTo","applyArgs","is","isGT","isGTE","isLT","isLTE","add","n","max","divide","generate","limit","modulo","multiply","randomInt","random","range","step","ceil","remainder","subtract","_immutable","obj","indexOf","freeze","getOwnPropertyNames","isNull","_keyToPair","_merge","getKeys","source","_setPathIn","parts","setter","headAsInt","parseInt","v","setIn","checker","message","keyPaths","pathSeparator","getValues","getPathIn","enumerables","keys","fromPairs","pairsList","pair","getIn","getPath","path","separator","split","has","immutable","make","values","valuesLen","pick","whitelist","pickIf","setKey","setPath","setPathIn","skip","blacklist","skipIf","validate","checkers","errors","_getPadding","char","repeat","padLeft","padRight","testWith","pattern","_reProto","test","bind","isType","typeName","_objectProto","toString","replace","lamb","create","_version","prototype","RegExp","generic","Function","reduceRight","drop","dropN","head","init","last","tail","take","takeN","union","zip","zipWithIndex","sorter","sorterDesc","pipe","wrap","isNot","_pairsFrom","_tearFrom","_valuesFrom","hasKey","hasKeyValue","hasOwn","hasOwnProperty","hasOwnKey","merge","mergeOwn","ownPairs","ownValues","pairs","tear","tearOwn","validateWith","isNil","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.21.0\n * @module lamb\n * @license MIT\n * @preserve\n */\n!function (host) {\n \"use strict\";\n\n var lamb = Object.create(null);\n\n /**\n * The current module version.\n * @memberof module:lamb\n * @private\n * @category Core\n * @type String\n */\n lamb._version = \"0.21.0\";\n\n // alias used as a placeholder argument for partial application\n var _ = lamb;\n\n // some prototype shortcuts for internal use\n var _arrayProto = Array.prototype;\n var _objectProto = Object.prototype;\n var _reProto = RegExp.prototype;\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 Core\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\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 getName = _.getKey(\"name\");\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, getName);\n *\n * users.map(sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @param {...Function} fn\n * @returns {Function}\n */\n function compose () {\n var functions = arguments;\n\n return function () {\n var args = arguments;\n var len = functions.length;\n\n while (len--) {\n args = [functions[len].apply(this, args)];\n }\n\n return args[0];\n };\n }\n\n /**\n * Creates generic functions out of methods.\n * @memberof module:lamb\n * @category Core\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}. Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @function\n * @example\n * // Lamb's \"filter\" is actually implemented like this\n * var filter = _.generic(Array.prototype.filter);\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 * @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 Core\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\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 used as a placeholder argument:\n * it's useful to alias it as _ or __.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n * var parseInt10 = _.partial(parseInt, _, 10);\n *\n * weights.map(parseInt10) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {...*} args\n * @returns {Function}\n */\n function partial (fn) {\n var args = slice(arguments, 1);\n\n return function () {\n var lastArgumentIdx = 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] = boundArg === _ ? arguments[lastArgumentIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastArgumentIdx < len; lastArgumentIdx++) {\n newArgs.push(arguments[lastArgumentIdx]);\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\n\n /**\n * Builds an array comprised of all values of the array-like object passing the predicate test.
\n * It's a generic version of [Array.prototype.filter]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter}.\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 * @function\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Array}\n */\n var filter = generic(_arrayProto.filter);\n\n /**\n * Executes the provided iteratee for each element of the given array-like object.
\n * It's a generic version of [Array.prototype.forEach]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach}.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment\n * var addClass = function (className) {\n * return function (element) {\n * element.classList.add(className);\n * };\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 * @function\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n */\n var forEach = generic(_arrayProto.forEach);\n\n /**\n * Creates an array from the results of the provided iteratee.
\n * It's a generic version of [Array.prototype.map]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map}.\n * @example\n * function getSquareRoots () {\n * return _.map(arguments, Math.sqrt);\n * }\n *\n * getSquareRoots(4, 9, 16) // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Array}\n */\n var map = generic(_arrayProto.map);\n\n /**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new value using the provided accumulator function.
\n * It's a generic version of [Array.prototype.reduce]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce}.\n * @example\n * _.reduce([1, 2, 3, 4], _.add) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduce = generic(_arrayProto.reduce);\n\n /**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last element instead.
\n * It's a generic version of [Array.prototype.reduceRight]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight}.\n * @memberof module:lamb\n * @category Array\n * @function\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduceRight = generic(_arrayProto.reduceRight);\n\n /**\n * Builds an array by extracting a portion of an array-like object.
\n * It's a generic version of [Array.prototype.slice]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice}.\n * @example\n * _.slice([\"foo\", \"bar\", \"baz\"], 0, 2) // => [\"foo\", \"bar\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} [start=0] - Zero-based index at which to begin extraction.\n * @param {Number} [end=arrayLike.length] - Zero-based index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\n var slice = generic(_arrayProto.slice);\n\n lamb.filter = filter;\n lamb.forEach = forEach;\n lamb.map = map;\n lamb.reduce = reduce;\n lamb.reduceRight = reduceRight;\n lamb.slice = slice;\n\n\n function _findSliceEndIndex (arrayLike, predicate, predicateContext) {\n var idx = -1;\n var len = arrayLike.length;\n\n while (++idx < len && predicate.call(predicateContext, arrayLike[idx], idx, arrayLike));\n\n return idx;\n }\n\n function _flatten (array, output) {\n array.forEach(function (value) {\n if (Array.isArray(value)) {\n _flatten(value, output);\n } else {\n output.push(value);\n }\n });\n\n return output;\n }\n\n function _groupWith (makeValue, startValue) {\n return function (arrayLike, iteratee, iterateeContext) {\n return reduce(arrayLike, function (result, element, idx) {\n var key = iteratee.call(iterateeContext, element, idx, arrayLike);\n var value = makeValue(key in result ? result[key] : startValue , element);\n\n result[key] = value;\n\n return result;\n }, {});\n };\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.isSVZ|isSVZ}; 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, 0);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @param {*} value\n * @param {Number} [fromIndex=0] The position at which to begin searching for the given value.\n * @returns {Function}\n */\n function contains (value, fromIndex) {\n return function (arrayLike) {\n return isIn(arrayLike, value, fromIndex);\n };\n }\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Object}\n */\n var count = _groupWith(partial(add, 1), 0);\n\n /**\n * Using the provided iteratee, and its optional context, builds a partial application of\n * {@link module:lamb.count|count} 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 * @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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Function}\n */\n function countBy (iteratee, iterateeContext) {\n return partial(count, _, iteratee, iterateeContext);\n }\n\n /**\n * Returns an array of items present only in the first of the given arrays.
\n * Note that since version 0.13.0 this function uses the [\"SameValueZero\" comparison]{@link module:lamb.isSVZ|isSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 4, 5];\n * var a3 = [4, 5, 3, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a1, a2, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @param {Array} array\n * @param {...Array} other\n * @returns {Array}\n */\n function difference (array) {\n var rest = shallowFlatten(slice(arguments, 1));\n var isInRest = partial(isIn, rest, _, 0);\n return array.filter(not(isInRest));\n }\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 * _.drop(arr, 2) // => [3, 4, 5]\n * _.drop(arr, -1) // => [5]\n * _.drop(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropN|dropN}\n * @see {@link module:lamb.take|take}, {@link module:lamb.takeN|takeN}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n var drop = binary(slice);\n\n /**\n * A curried version of {@link module:lamb.drop|drop} 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.drop|drop} about passing a negative n.\n * @example\n * var drop2 = _.dropN(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.take|take}, {@link module:lamb.takeN|takeN}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var dropN = _curry(drop, 2, true);\n\n /**\n * Builds a function that drops the first n elements satisfying a predicate 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.drop|drop}, {@link module:lamb.dropN|dropN}\n * @see {@link module:lamb.take|take}, {@link module:lamb.takeN|takeN}\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function dropWhile (predicate, predicateContext) {\n return function (arrayLike) {\n return slice(arrayLike, _findSliceEndIndex(arrayLike, predicate, predicateContext));\n };\n }\n\n /**\n * Returns a partial application of {@link module:lamb.filter|filter} that uses the given predicate and\n * the optional context 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 * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function filterWith (predicate, predicateContext) {\n return partial(filter, _, predicate, predicateContext);\n }\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {*}\n */\n function find (arrayLike, predicate, predicateContext) {\n var result;\n\n for (var i = 0, len = arrayLike.length, element; i < len; i++) {\n element = arrayLike[i];\n\n if (predicate.call(predicateContext, element, i, arrayLike)) {\n result = element;\n break;\n }\n }\n\n return result;\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Number}\n */\n function findIndex (arrayLike, predicate, predicateContext) {\n var result = -1;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (predicate.call(predicateContext, arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\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 * @function\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Array}\n */\n var flatMap = compose(shallowFlatten, map);\n\n /**\n * Builds a partial application of {@link module:lamb.flatMap|flatMap} using the given iteratee\n * and the optional context. The resulting function expects 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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Function}\n */\n function flatMapWith (iteratee, iterateeContext) {\n return partial(flatMap, _, iteratee, iterateeContext);\n }\n\n /**\n * Flattens an array. See also {@link module:lamb.shallowFlatten|shallowFlatten}.\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 * @param {Array} array\n * @returns {Array}\n */\n function flatten (array) {\n return _flatten(array, []);\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 * @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 * @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 function getAt (index) {\n return function (arrayLike) {\n return Math.floor(index) === index ? arrayLike[index < 0 ? index + arrayLike.length : index] : void 0;\n };\n }\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Object}\n */\n var group = _groupWith(invoker(\"concat\"), []);\n\n /**\n * Using the provided iteratee, and its optional context, builds a partial application\n * of {@link module:lamb.group|group} 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 * @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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Function}\n */\n function groupBy (iteratee, iterateeContext) {\n return partial(group, _, iteratee, iterateeContext);\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 * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var head = getAt(0);\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Object}\n */\n var index = _groupWith(getArgAt(1));\n\n /**\n * Using the provided iteratee, and its optional context, builds a partial application\n * of {@link module:lamb.index|index} 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 * @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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Function}\n */\n function indexBy (iteratee, iterateeContext) {\n return partial(index, _, iteratee, iterateeContext);\n }\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 * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var init = partial(slice, _, 0, -1);\n\n /**\n * Returns an array of every item present in all given arrays.
\n * Note that since version 0.13.0 this function uses the [\"SameValueZero\" comparison]{@link module:lamb.isSVZ|isSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @param {...Array} array\n * @return {Array}\n */\n function intersection () {\n var rest = slice(arguments, 1);\n return uniques(arguments[0]).filter(function (item) {\n return rest.every(contains(item));\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.isSVZ|isSVZ}; 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, 2, 3) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @param {Number} [fromIndex=0] The position at which to begin searching for the given value.\n * @returns {Boolean}\n */\n function isIn (arrayLike, value, fromIndex) {\n var result = false;\n\n for (var i = fromIndex >>> 0, len = arrayLike.length; i < len; i++) {\n if (isSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n }\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 * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var last = getAt(-1);\n\n /**\n * Generates an array with the values passed as arguments.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @param {...*} value\n * @returns {Array}\n */\n function list () {\n return arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.map|map} using the given iteratee and the optional context.\n * The resulting function expects 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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {function}\n */\n function mapWith (iteratee, iterateeContext) {\n return partial(map, _, iteratee, iterateeContext);\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Array, Array<*>>}\n */\n function partition (arrayLike, predicate, predicateContext) {\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.call(predicateContext, el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.partition|partition} using the given predicate and the optional context.\n * The resulting function expects 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 * @see {@link module:lamb.partition|partition}\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function partitionWith (predicate, predicateContext) {\n return partial(partition, _, predicate, predicateContext);\n }\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 * @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 * @see {@link module:lamb.pluck|pluck}\n * @function\n * @param {String} key\n * @returns {Function}\n */\n function pluckKey (key) {\n return mapWith(getKey(key));\n }\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 * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function reverse (arrayLike) {\n return slice(arrayLike).reverse();\n }\n\n /**\n * Builds a function that creates a copy of an array-like object with the given\n * index changed to the provided 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 * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\n function setAt (index, value) {\n return function (arrayLike) {\n var result = slice(arrayLike);\n var len = arrayLike.length;\n\n if (clamp(index, -len, len - 1) === Math.floor(index)) {\n result[index + (index < 0 ? len : 0)] = value;\n }\n\n return result;\n };\n }\n\n /**\n * Flattens the \"first level\" of an array.
\n * See also {@link module:lamb.flatten|flatten}.\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 * @param {Array} array\n * @returns {Array}\n */\n function shallowFlatten (array) {\n return _arrayProto.concat.apply([], array);\n }\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 * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var tail = partial(slice, _, 1, void 0);\n\n /**\n * Retrieves the first n elements from an array or array-like object.\n * Note that, being this a partial application 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 * _.take(arr, 3) // => [1, 2, 3]\n * _.take(arr, -1) // => [1, 2, 3, 4]\n * _.take(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeN|takeN}\n * @see {@link module:lamb.drop|drop}, {@link module:lamb.dropN|dropN}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n var take = partial(slice, _, 0, _);\n\n /**\n * A curried version of {@link module:lamb.take|take} 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.take|take} about passing a negative n.\n * @example\n * var take2 = _.takeN(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.take|take}\n * @see {@link module:lamb.drop|drop}, {@link module:lamb.dropN|dropN}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var takeN = _curry(take, 2, true);\n\n /**\n * Builds a function that takes the first n elements satisfying a predicate from 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.take|take}, {@link module:lamb.takeN|takeN}\n * @see {@link module:lamb.drop|drop}, {@link module:lamb.dropN|dropN}\n * @param {ListIteratorCallback} predicate\n * @param {Object} predicateContext\n * @returns {Function}\n */\n function takeWhile (predicate, predicateContext) {\n return function (arrayLike) {\n return slice(arrayLike, 0, _findSliceEndIndex(arrayLike, predicate, predicateContext));\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 * @param {ArrayLike>} arrayLike\n * @returns {Array>}\n */\n function transpose (arrayLike) {\n var result = [];\n var minLen = apply(Math.min, pluck(arrayLike, \"length\")) >>> 0;\n var len = arrayLike.length;\n\n for (var i = 0, j; i < minLen; i++) {\n result.push([]);\n\n for (j = 0; j < len; j++) {\n result[i][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 * @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 * @param {...ArrayLike} arrayLike\n * @returns {Array}\n */\n var union = compose(uniques, flatMapWith(unary(slice)), list);\n\n /**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Can work with lists of complex objects if supplied with an iteratee.
\n * Note that since version 0.13.0 this function uses the [\"SameValueZero\" comparison]{@link module:lamb.isSVZ|isSVZ}.\n * @example with simple values\n * _.uniques([1, 2, 2, 3, 4, 3, 5, 1]) // => [1, 2, 3, 4, 5]\n *\n * @example with complex values\n * var data = [\n * {id: \"1\"},\n * {id: \"4\"},\n * {id: \"5\"},\n * {id: \"1\"},\n * {id: \"5\"},\n * ];\n *\n * _.uniques(data, _.getKey(\"id\")) // => [{id: \"1\"}, {id: \"4\"}, {\"id\": 5}]\n *\n * @memberof module:lamb\n * @category Array\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} [iteratee] Defaults to the [identity function]{@link module:lamb.identity}.\n * @param {Object} [iterateeContext]\n * @returns {Array}\n */\n function uniques (arrayLike, iteratee, iterateeContext) {\n if (typeof iteratee !== \"function\") {\n iteratee = identity;\n }\n\n var result = [];\n var seen = [];\n var value;\n\n for (var i = 0; i < arrayLike.length; i++) {\n value = iteratee.call(iterateeContext, arrayLike[i], i , arrayLike);\n\n if (!isIn(seen, value)) {\n seen.push(value);\n result.push(arrayLike[i]);\n }\n }\n\n return result;\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 * See also {@link module:lamb.zipWithIndex|zipWithIndex} and {@link module:lamb.transpose|transpose} for the reverse operation.\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 * @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 * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\n var zipWithIndex = mapWith(binary(list));\n\n lamb.contains = contains;\n lamb.count = count;\n lamb.countBy = countBy;\n lamb.difference = difference;\n lamb.drop = drop;\n lamb.dropN = dropN;\n lamb.dropWhile = dropWhile;\n lamb.filterWith = filterWith;\n lamb.find = find;\n lamb.findIndex = findIndex;\n lamb.flatMap = flatMap;\n lamb.flatMapWith = flatMapWith;\n lamb.flatten = flatten;\n lamb.getAt = getAt;\n lamb.group = group;\n lamb.groupBy = groupBy;\n lamb.head = head;\n lamb.index = index;\n lamb.indexBy = indexBy;\n lamb.init = init;\n lamb.intersection = intersection;\n lamb.isIn = isIn;\n lamb.last = last;\n lamb.list = list;\n lamb.mapWith = mapWith;\n lamb.partition = partition;\n lamb.partitionWith = partitionWith;\n lamb.pluck = pluck;\n lamb.pluckKey = pluckKey;\n lamb.reverse = reverse;\n lamb.setAt = setAt;\n lamb.shallowFlatten = shallowFlatten;\n lamb.tail = tail;\n lamb.take = take;\n lamb.takeN = takeN;\n lamb.takeWhile = takeWhile;\n lamb.transpose = transpose;\n lamb.union = union;\n lamb.uniques = uniques;\n lamb.zip = zip;\n lamb.zipWithIndex = zipWithIndex;\n\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 if (!isSVZ(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 return result;\n }\n\n function _compareWith (criteria) {\n var len = criteria.length;\n\n return function (a, b) {\n var result = 0;\n var isDescSort;\n var criterion;\n\n for (var i = 0; i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n\n if (result !== 0) {\n isDescSort = criteria[i].isDescending;\n break;\n }\n }\n\n if (result === 0) {\n isDescSort = criteria[len - 1].isDescending;\n result = a.index - b.index;\n }\n\n return isDescSort ? -result : result;\n };\n }\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,\n index: pivot\n }, {\n value: array[pivot],\n 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 function _makeCriteria (sorters) {\n return sorters.length ? sorters.map(_makeCriterion) : [_sorter()];\n }\n\n function _makeCriterion (criterion) {\n return typeof Object(criterion).compare === \"function\" ? criterion : _sorter(criterion);\n }\n\n function _sorter (reader, isDescending, comparer) {\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (typeof reader === \"function\" && reader !== identity) {\n a = reader(a);\n b = reader(b);\n }\n\n return (comparer || _comparer)(a, b);\n }\n };\n }\n\n /**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example with simple values\n * _.insert([], 1) // => [1]\n * _.insert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.insert([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 = _.insert(\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 * @param {Array} array\n * @param {*} element\n * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}] - The sorting criteria used to sort the array.\n * @returns {Array}\n */\n function insert (array, element) {\n var criteria = _makeCriteria(slice(arguments, 2));\n var result = array.concat();\n var idx = _getInsertionIndex(array, element, _compareWith(criteria), 0, array.length);\n\n result.splice(idx, 0, element);\n return result;\n }\n\n /**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted copy of an\n * array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you can also\n * 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 in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type, 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 * @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(slice(arguments, 1));\n var data = [];\n var result = [];\n var len = arrayLike.length;\n\n for (var i = 0; i < len; i++) {\n data.push({\n value: arrayLike[i],\n index: i\n });\n }\n\n data.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result.push(data[i].value);\n }\n\n return result;\n }\n\n /**\n * Creates an ascending sort criterion with the provided reader and 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.insert|insert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a simple value from a complex one. The function should evaluate the array element and supply the 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 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.insert|insert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a simple value from a complex one. The function should evaluate the array element and supply the 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. The returned\n * function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you can also\n * 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 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 * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}]\n * @returns {Function}\n */\n function sortWith () {\n var sorters = slice(arguments);\n\n return function (arrayLike) {\n return sort.apply(null, [arrayLike].concat(sorters));\n };\n }\n\n lamb.insert = insert;\n lamb.sort = sort;\n lamb.sorter = sorter;\n lamb.sorterDesc = sorterDesc;\n lamb.sortWith = sortWith;\n\n\n function _currier (fn, arity, isRightCurry, slicer, argsHolder) {\n return function () {\n var args = argsHolder.concat(slicer(arguments));\n\n if (args.length >= arity) {\n return fn.apply(this, isRightCurry ? args.reverse() : args);\n } else {\n return _currier(fn, arity, isRightCurry, slicer, args);\n }\n };\n }\n\n function _curry (fn, arity, isRightCurry, isAutoCurry) {\n var slicer = isAutoCurry ? slice : function (a) {\n return a.length ? [a[0]] : [];\n };\n\n if ((arity >>> 0) !== arity) {\n arity = fn.length;\n }\n\n return _currier(fn, arity, isRightCurry, slicer, []);\n }\n\n /**\n * Applies the passed function to the given argument list.\n * @example\n * _.apply(_.add, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\n function apply (fn, args) {\n return fn.apply(fn, slice(args));\n }\n\n /**\n * A curried version of {@link module:lamb.apply|apply}. Expects an array-like object to use as arguments\n * and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyDataTo = _.applyArgs(data);\n *\n * applyDataTo(_.add) // => 7\n * applyDataTo(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @param {ArrayLike} args\n * @returns {Function}\n */\n var applyArgs = _curry(apply, 2, true);\n\n /**\n * Builds a function that passes only the specified amount of arguments to the given function.
\n * See also {@link module:lamb.binary|binary} and {@link module:lamb.unary|unary} for common use\n * cases shortcuts.\n * @example\n * var data = [\"1-2\", \"13-5\", \"6-23\"];\n * var getDashIndex = _.invoker(\"indexOf\", \"-\");\n *\n * data.map(getDashIndex) // => [1, 2, -1]\n * data.map(_.aritize(getDashIndex, 1)) // = > [1, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\n function aritize (fn, arity) {\n return function () {\n return apply(fn, slice(arguments, 0, arity));\n };\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 * See also {@link module:lamb.unary|unary}.\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 * @param {Function} fn\n * @returns {Function}\n */\n function binary (fn) {\n return function (a, b) {\n return fn(a, b);\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 * See also {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * and {@link module:lamb.partial|partial}.\n * @example\n * var multiplyBy = _.curry(_.multiply);\n * var multiplyBy10 = multiplyBy(10);\n *\n * multiplyBy10(5) // => 50\n * multiplyBy10()(5) // => 50\n * multiplyBy10()()(2) // => 20\n *\n * @memberof module:lamb\n * @category Function\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 * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var divideBy = _.curryRight(_.divide);\n * var halve = divideBy(2);\n * halve(3) // => 1.5\n * halve(3, 7) // => 1.5\n *\n * @memberof module:lamb\n * @category Function\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 * 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 * Note that you can pass undefined values as arguments explicitly, if you are so inclined, but empty\n * calls doesn't consume the arity.
\n * See also {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight} and\n * {@link module:lamb.partial|partial}.\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 * @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 * @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 * Returns a function that will execute the given function only if it stops being called for the specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call 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 * @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 context = this;\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(context, args);\n };\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n }\n\n /**\n * Returns a function that applies its arguments to the original function 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 * @param {Function} fn\n * @returns {Function}\n */\n function flip (fn) {\n return function () {\n var args = slice(arguments).reverse();\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 * @param {Number} index\n * @returns {Function}\n */\n function getArgAt (index) {\n return compose(getAt(index), list);\n }\n\n /**\n * Accepts an object and builds a function expecting a method name, and optionally arguments, to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the 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 * @param {Object} target\n * @returns {Function}\n */\n function invokerOn (target) {\n return function (methodName) {\n var args = slice(arguments, 1);\n var method = target[methodName];\n return type(method) === \"Function\" ? method.apply(target, args) : void 0;\n };\n }\n\n /**\n * Builds a function that will invoke the given method name on any received object and return\n * the result. If no method with such name is found the function will return undefined.\n * Along with the method name it's possible to supply some arguments that will be bound to the method call.
\n * Further arguments can also be passed when the function is actually called, and they will be concatenated\n * to the bound ones.
\n * If different objects share a method name it's possible to build polymorphic functions as you can see in\n * the example below.
\n * {@link module:lamb.condition|Condition} can be used to wrap invoker to avoid this behaviour\n * by adding a predicate, while {@link module:lamb.adapter|adapter} can build more complex polymorphic functions\n * without the need of homonymy.
\n * Returning undefined or checking for such value is meant to favor composition and interoperability\n * between the aforementioned functions: for a more standard behaviour see also {@link module:lamb.generic|generic}.\n * See also {@link module:lamb.invokerOn|invokerOn}.\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 * @param {String} methodName\n * @param {...*} [boundArg]\n * @returns {Function}\n */\n function invoker (methodName) {\n var boundArgs = slice(arguments, 1);\n\n return function (target) {\n var args = slice(arguments, 1);\n var method = target[methodName];\n return type(method) === \"Function\" ? method.apply(target, boundArgs.concat(args)) : void 0;\n };\n }\n\n /**\n * Builds a function that allows to map over the received arguments before applying them to the original one.\n * @example\n * var sumArray = _.invoker(\"reduce\", _.add);\n * var sum = _.compose(sumArray, _.list);\n *\n * sum(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, _, 2);\n * var sumSquares = _.mapArgs(sum, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\n function mapArgs (fn, mapper) {\n return compose(partial(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 * See also {@link module:lamb.compose|compose}.\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 * @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(_.add, _.getKey(\"count\"), _.getKey(\"length\"));\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {...?Function} [tapper]\n * @returns {Function}\n */\n function tapArgs (fn) {\n var readers = slice(arguments, 1);\n\n return function () {\n var len = arguments.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(readers[i] ? readers[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 {@link module:lamb.debounce|debounce}\n * 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 * @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 * See also {@link module:lamb.binary|binary}.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * weights.map(_.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @returns {Function}\n */\n function unary (fn) {\n return function (a) {\n return fn(a);\n };\n }\n\n /**\n * Wraps the function fn inside a wrapper function.
\n * This allows to conditionally execute fn, to tamper with its arguments or return value\n * and to run code before and after its execution.
\n * Being this nothing more than a \"{@link module:lamb.flip|flipped}\" [partial application]{@link module:lamb.partial},\n * you can also easily build new functions from existent ones.\n * @example\n * var arrayMax = _.wrap(Math.max, _.apply);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @param {Function} fn\n * @param {Function} wrapper\n * @returns {Function}\n */\n var wrap = binary(flip(partial));\n\n lamb.apply = apply;\n lamb.applyArgs = applyArgs;\n lamb.aritize = aritize;\n lamb.binary = binary;\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.invokerOn = invokerOn;\n lamb.invoker = invoker;\n lamb.mapArgs = mapArgs;\n lamb.pipe = pipe;\n lamb.tapArgs = tapArgs;\n lamb.throttle = throttle;\n lamb.unary = unary;\n lamb.wrap = wrap;\n\n\n /**\n * Accepts a series of functions and builds a function that applies the received arguments to each one and\n * returns the first non undefined value.
\n * Meant to work in sinergy with {@link module:lamb.condition|condition} and {@link module:lamb.invoker|invoker},\n * can be useful as a strategy pattern for functions, to mimic conditional logic 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 * _.condition(_.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 * @param {...Function} fn\n * @returns {Function}\n */\n function adapter () {\n var functions = slice(arguments);\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = apply(functions[i], arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n }\n\n /**\n * Builds a predicate that returns true if all the given predicates are satisfied.\n * The arguments passed to the resulting function are applied to every predicate unless one of them returns false.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositive = function (n) { return n > 0; };\n * var isPositiveEven = _.allOf(isEven, isPositive);\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 * @param {...Function} predicate\n * @returns {Function}\n */\n function allOf () {\n var predicates = slice(arguments);\n\n return function () {\n var args = arguments;\n\n return predicates.every(function (predicate) {\n return predicate.apply(null, args);\n });\n };\n }\n\n /**\n * Builds a predicate that returns true if at least one of the given predicates is satisfied.\n * The arguments passed to the resulting function are applied to every predicate until one of them returns true.\n * @example\n * // Lamb's \"isNil\" is actually implemented like this\n * var isNil = _.anyOf(_.isNull, _.isUndefined);\n *\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 Logic\n * @see {@link module:lamb.allOf|allOf}\n * @param {...Function} predicate\n * @returns {Function}\n */\n function anyOf () {\n var predicates = slice(arguments);\n\n return function () {\n var args = arguments;\n\n return predicates.some(function (predicate) {\n return predicate.apply(null, args);\n });\n };\n }\n\n /**\n * Builds a function that will apply the received arguments to trueFn, if the predicate is satisfied with\n * the same arguments, or to falseFn otherwise.
\n * If falseFn isn't provided and the predicate isn't satisfied the function will return undefined.
\n * Although you can use other conditions as trueFn or falseFn, it's probably better to\n * use {@link module:lamb.adapter|adapter} to build more complex behaviours.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halve = function (n) { return n / 2; };\n * var halveIfEven = _.condition(isEven, halve, _.identity);\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.invoker|invoker}\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 var applyArgsTo = applyArgs(arguments);\n return applyArgsTo(predicate) ? applyArgsTo(trueFn) : falseFn ? applyArgsTo(falseFn) : void 0;\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, NaN is equal to itself.
\n * See also {@link module:lamb.isSVZ|isSVZ} which performs the check using the \"SameValueZero\" comparison.\n * @example\n * var testObject = {};\n *\n * _.is({}, testObject) // => false\n * _.is(testObject, testObject) // => true\n * _.is(\"foo\", \"foo\") // => true\n * _.is(0, -0) // => false\n * _.is(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see [SameValue comparison]{@link https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero}\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function is (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : isSVZ(a, b);\n }\n\n /**\n * Verifies that the first given value is greater than the second.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.isGT(today, pastDate) // true\n * _.isGT(pastDate, today) // false\n * _.isGT(3, 4) // false\n * _.isGT(3, 3) // false\n * _.isGT(3, 2) // true\n * _.isGT(0, -0) // false\n * _.isGT(-0, 0) // false\n * _.isGT(\"a\", \"A\") // true\n * _.isGT(\"b\", \"a\") // true\n *\n * @memberof module:lamb\n * @category Logic\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function isGT (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 operator, so -0 === 0.\n * @example\n * _.isGTE(3, 4) // false\n * _.isGTE(3, 3) // true\n * _.isGTE(3, 2) // true\n * _.isGTE(0, -0) // true\n * _.isGTE(-0, 0) // true\n *\n * @memberof module:lamb\n * @category Logic\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function isGTE (a, b) {\n return a >= b;\n }\n\n /**\n * Verifies that the first given value is less than the second.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.isLT(today, pastDate) // false\n * _.isLT(pastDate, today) // true\n * _.isLT(3, 4) // true\n * _.isLT(3, 3) // false\n * _.isLT(3, 2) // false\n * _.isLT(0, -0) // false\n * _.isLT(-0, 0) // false\n * _.isLT(\"a\", \"A\") // false\n * _.isLT(\"a\", \"b\") // true\n *\n * @memberof module:lamb\n * @category Logic\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function isLT (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 operator, so -0 === 0.\n * @example\n * _.isLTE(3, 4) // true\n * _.isLTE(3, 3) // true\n * _.isLTE(3, 2) // false\n * _.isLTE(0, -0) // true\n * _.isLTE(-0, 0) // true\n *\n * @memberof module:lamb\n * @category Logic\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function isLTE (a, b) {\n return a <= b;\n }\n\n /**\n * A simple negation of {@link module:lamb.is|is}, exposed for convenience.\n * @example\n * _.isNot(\"foo\", \"foo\") // => false\n * _.isNot(0, -0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @param {*} valueA\n * @param {*} valueB\n * @returns {Boolean}\n */\n var isNot = not(is);\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 too.
\n * See also {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.isSVZ({}, testObject) // => false\n * _.isSVZ(testObject, testObject) // => true\n * _.isSVZ(\"foo\", \"foo\") // => true\n * _.isSVZ(0, -0) // => true\n * _.isSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see [SameValue comparison]{@link https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero}\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function isSVZ (a, b) {\n return a !== a ? b !== b : 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 * @param {Function} predicate\n * @returns {Function}\n */\n function not (predicate) {\n return function () {\n return !predicate.apply(null, arguments);\n };\n }\n\n lamb.adapter = adapter;\n lamb.allOf = allOf;\n lamb.anyOf = anyOf;\n lamb.condition = condition;\n lamb.is = is;\n lamb.isGT = isGT;\n lamb.isGTE = isGTE;\n lamb.isLT = isLT;\n lamb.isLTE = isLTE;\n lamb.isNot = isNot;\n lamb.isSVZ = isSVZ;\n lamb.not = not;\n\n\n /**\n * Adds two numbers.\n * @example\n * _.add(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function add (a, b) {\n return a + b;\n }\n\n /**\n * \"Clamps\" a number within the given limits.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function clamp (n, min, max) {\n return n < min ? min : n > max ? max : n;\n }\n\n /**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\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 * 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 * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Array}\n */\n function generate (start, len, iteratee, iterateeContext) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee.call(iterateeContext, result[i], i, result));\n }\n\n return result;\n }\n\n /**\n * Performs the modulo operation and should not be confused with the {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not a truncated one, hence the sign of\n * the dividend is not kept, unlike the {@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 http://en.wikipedia.org/wiki/Modulo_operation}\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 * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function multiply (a, b) {\n return a * b;\n }\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 * @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(2, 10, 0) // => [2]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(1, -10, 2) // => [1]\n *\n * @memberof module:lamb\n * @category Math\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\n function range (start, limit, step) {\n if (step === 0 || arguments.length < 2) {\n return [start];\n }\n\n if (!step) {\n step = 1;\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n return generate(start, len, partial(add, step));\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 http://en.wikipedia.org/wiki/Modulo_operation}\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 * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function subtract (a, b) {\n return a - b;\n }\n\n lamb.add = add;\n lamb.clamp = clamp;\n lamb.divide = divide;\n lamb.generate = generate;\n lamb.modulo = modulo;\n lamb.multiply = multiply;\n lamb.randomInt = randomInt;\n lamb.range = range;\n lamb.remainder = remainder;\n lamb.subtract = subtract;\n\n\n function _immutable (obj, seen) {\n if (seen.indexOf(obj) === -1) {\n seen.push(Object.freeze(obj));\n\n Object.getOwnPropertyNames(obj).forEach(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 function _keyToPair (key) {\n return [key, this[key]];\n }\n\n function _merge (getKeys) {\n return reduce(slice(arguments, 1), function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n }\n\n var _pairsFrom = _curry(function (getKeys, obj) {\n return getKeys(obj).map(_keyToPair, obj);\n });\n\n function _setPathIn (obj, parts, value) {\n var headAsInt = parseInt(parts[0], 10);\n var target;\n var setter;\n\n if (Array.isArray(obj) && headAsInt == parts[0]) {\n target = getAt(headAsInt)(obj);\n setter = function (v) {\n return setAt(headAsInt, v)(obj);\n };\n } else {\n target = (obj || {})[parts[0]];\n setter = partial(setIn, obj, parts[0]);\n }\n\n return setter(\n parts.length < 2 ? value : _setPathIn(target, parts.slice(1), value)\n );\n }\n\n var _tearFrom = _curry(function (getKeys, obj) {\n return getKeys(obj).reduce(function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n return result;\n }, [[], []]);\n });\n\n var _valuesFrom = _curry(function (getKeys, obj) {\n return getKeys(obj).map(partial(getIn, obj));\n });\n\n /**\n * Builds a checker function meant to be used with {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to compare their values. In\n * other words all the received keyPaths will be passed as arguments to the predicate\n * 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 * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of property names, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Array} An error in the form [\"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 return predicate.apply(obj, keyPaths.map(getValues)) ? [] : [message, keyPaths];\n };\n }\n\n /**\n * Creates an array with all the enumerable properties of the given object.\n * @example showing the difference with Object.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 * Object.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @see [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * @param {Object} obj\n * @returns {String[]}\n */\n function enumerables (obj) {\n var keys = [];\n\n for (var key in obj) {\n keys.push(key);\n }\n\n return keys;\n }\n\n /**\n * Builds an object from a list of key / value pairs like the one\n * returned by [pairs]{@link module:lamb.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 * @param {Array>} pairsList\n * @returns {Object}\n */\n function fromPairs (pairsList) {\n var result = {};\n\n pairsList.forEach(function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n }\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 * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\n function getIn (obj, key) {\n return obj[key];\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 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 * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @function\n * @param {String} key\n * @returns {Function}\n */\n var getKey = _curry(getIn, 2, 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 * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function getPath (path, separator) {\n return partial(getPathIn, _, path, separator);\n }\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 * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * // same as _.getIn if no path is involved\n * _.getPathIn(user, \"name\") // => \"John\"\n *\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 * @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 * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\n function getPathIn (obj, path, separator) {\n return path.split(separator || \".\").reduce(tapArgs(getIn, Object), obj);\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 * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function has (obj, key) {\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 * @param {String} key\n * @returns {Function}\n */\n var hasKey = _curry(has, 2, true);\n\n /**\n * Builds a function expecting an object to check against the given key / value pair.\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 * @function\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n var hasKeyValue = function (key, value) {\n return compose(partial(is, value), getKey(key));\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 * @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 * @param {String} key\n * @returns {Function}\n */\n var hasOwnKey = _curry(hasOwn, 2, true);\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 * @param {Object} obj\n * @returns {Object}\n */\n function immutable (obj) {\n return _immutable(obj, []);\n }\n\n /**\n * Builds an object from the two given lists, using the first one as keys and the last one as values.
\n * If the list of keys is longer than the values one, the keys will be created with undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.
\n * See also {@link module:lamb.tear|tear} and {@link module:lamb.tearOwn|tearOwn} for the reverse operation.\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 * @param {String[]} keys\n * @param {Array} values\n * @returns {Object}\n */\n function make (keys, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = keys.length; i < len; i++) {\n result[keys[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n }\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 * See also {@link module:lamb.mergeOwn|mergeOwn} for merging only own properties of\n * the given sources.\n * @example\n * _.merge({a: 1}, {b: 3, c: 4}, {b: 5}) // => {a: 1, b: 5, c: 4}\n *\n * @example Arrays or 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 value will be treated as an empty object:\n * _.merge({a: 2}, null, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\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 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 Arrays or 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 value will be treated as an empty object:\n * _.mergeOwn({a: 2}, null, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @param {...Object} source\n * @returns {Object}\n */\n var mergeOwn = partial(_merge, compose(Object.keys, Object));\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 * @param {Object} obj\n * @returns {Array>}\n */\n var ownPairs = _pairsFrom(Object.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 * @param {Object} obj\n * @returns {Array}\n */\n var ownValues = _valuesFrom(Object.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 * @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}\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\n function pick (source, whitelist) {\n var result = {};\n\n whitelist.forEach(function (key) {\n if (key in source) {\n result[key] = source[key];\n }\n });\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose properties will be checked 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}\n * @param {ObjectIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function pickIf (predicate, predicateContext) {\n return function (source) {\n var result = {};\n\n for (var key in source) {\n if (predicate.call(predicateContext, source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n }\n\n /**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the enumerable keys of the source object will be simply copied to an empty\n * 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 *\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 * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function setIn (source, key, value) {\n return _merge(enumerables, source, make([key], [value]));\n }\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 * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n function setKey (key, value) {\n return partial(setIn, _, key, value);\n }\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 * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function setPath (path, value, separator) {\n return partial(setPathIn, _, path, value, separator);\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 * 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 * @param {Object|Array} obj\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function setPathIn (obj, path, value, separator) {\n return _setPathIn(obj, path.split(separator || \".\"), value);\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.skipIf|skipIf}\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\n function skip (source, blacklist) {\n var result = {};\n\n for (var key in source) {\n if (blacklist.indexOf(key) === -1) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose properties will be checked 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 * @see {@link module:lamb.skip|skip}\n * @param {ObjectIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function skipIf (predicate, predicateContext) {\n return pickIf(not(predicate), predicateContext);\n }\n\n /**\n * Tears an object apart by transforming it in an array of two lists: one containing its enumerable keys,\n * the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source object will be unharmed.
\n * See also {@link module:lamb.tearOwn|tearOwn} for picking only the own enumerable properties and\n * {@link module:lamb.make|make} for the reverse operation.\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 * @param {Object} obj\n * @returns {Array, 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 taken into account.
\n * See also {@link module:lamb.make|make} for the reverse operation.\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 * @param {Object} obj\n * @returns {Array, Array<*>>}\n */\n var tearOwn = _tearFrom(Object.keys);\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 isAdult = function (age) { return age >= 18; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(isAdult, \"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) // => [[\"Surname is required\", [\"surname\"]], [\"Must be at least 18 years old\", [\"age\"]]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by {@link module:lamb.checker|checker}, or an empty array.\n */\n function validate (obj, checkers) {\n return checkers.reduce(function (errors, checker) {\n var result = checker(obj);\n result.length && errors.push(result);\n return errors;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of {@link module:lamb.checker|checkers} and\n * returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var isAdult = function (age) { return age >= 18; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(isAdult, \"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) // => [[\"Surname is required\", [\"surname\"]], [\"Must be at least 18 years old\", [\"age\"]]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @function\n * @param {Function[]} checkers\n * @returns {Function}\n */\n var validateWith = _curry(validate, 2, true);\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} for picking only 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 * @param {Object} obj\n * @returns {Array}\n */\n var values = _valuesFrom(enumerables);\n\n lamb.checker = checker;\n lamb.enumerables = enumerables;\n lamb.fromPairs = fromPairs;\n lamb.getIn = getIn;\n lamb.getKey = getKey;\n lamb.getPath = getPath;\n lamb.getPathIn = getPathIn;\n lamb.has = has;\n lamb.hasKey = hasKey;\n lamb.hasKeyValue = hasKeyValue;\n lamb.hasOwn = hasOwn;\n lamb.hasOwnKey = hasOwnKey;\n lamb.immutable = immutable;\n lamb.make = make;\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.setIn = setIn;\n lamb.setKey = setKey;\n lamb.setPath = setPath;\n lamb.setPathIn = setPathIn;\n lamb.skip = skip;\n lamb.skipIf = skipIf;\n lamb.tear = tear;\n lamb.tearOwn = tearOwn;\n lamb.validate = validate;\n lamb.validateWith = validateWith;\n lamb.values = values;\n\n\n function _getPadding (source, char, len) {\n return repeat(char[0] || \" \", Math.ceil(len - source.length));\n }\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 * @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 * @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 [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 count is negative, 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 * @param {String} source\n * @param {Number} count\n * @returns {String}\n */\n function repeat (source, count) {\n var result = \"\";\n\n for (var i = 0; i < count; i++) {\n result += source;\n }\n\n return result;\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 * @param {RegExp} pattern\n * @returns {Function}\n */\n function testWith (pattern) {\n return _reProto.test.bind(pattern);\n }\n\n lamb.padLeft = padLeft;\n lamb.padRight = padRight;\n lamb.repeat = repeat;\n lamb.testWith = testWith;\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} and {@link module:lamb.isNull|isUndefined} for individual checks.\n * @function\n * @param {*} value\n * @returns {Boolean}\n */\n var isNil = anyOf(isNull, isUndefined);\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 * @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 * @param {String} typeTag\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 * @param {*} value\n * @returns {Boolean}\n */\n function isUndefined (value) {\n // using void because undefined could be theoretically shadowed\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 * @param {*} value\n * @returns {String}\n */\n function type (value) {\n return _objectProto.toString.call(value).replace(/^\\[\\w+\\s+|\\]$/g, \"\");\n }\n\n lamb.isNil = isNil;\n lamb.isNull = isNull;\n lamb.isType = isType;\n lamb.isUndefined = isUndefined;\n lamb.type = type;\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() { return lamb; });\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 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 * Represent a sorting criteria used by {@link module:lamb.insert|insert}, {@link module:lamb.sort|sort} and {@link module:lamb.sortWith|sortWith},\n * and it's 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"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["lamb.js"],"names":["host","always","value","compose","functions","arguments","args","len","length","apply","this","identity","partial","fn","slice","boundArg","lastArgumentIdx","newArgs","argsLen","i","_","push","_findSliceEndIndex","arrayLike","predicate","predicateContext","idx","call","_flatten","array","output","forEach","Array","isArray","_getPositiveIndex","index","clamp","Math","floor","_groupWith","makeValue","startValue","iteratee","iterateeContext","reduce","result","element","key","_setIndex","updater","isUndefined","contains","fromIndex","isIn","countBy","count","difference","rest","shallowFlatten","isInRest","filter","not","dropWhile","filterWith","find","findIndex","flatMapWith","flatMap","flatten","getAt","groupBy","group","indexBy","intersection","uniques","item","every","isSVZ","list","mapWith","map","partition","el","partitionWith","pluck","getKey","pluckKey","reverse","setAt","_arrayProto","concat","takeWhile","transpose","j","minLen","min","seen","updateAt","_comparer","a","b","String","_compareWith","criteria","isDescSort","criterion","compare","isDescending","_getInsertionIndex","comparer","start","end","pivot","_makeCriteria","sorters","_makeCriterion","_sorter","Object","reader","insert","splice","sort","data","sortWith","_currier","arity","isRightCurry","slicer","argsHolder","_curry","isAutoCurry","aritize","binary","curry","curryRight","curryable","curryableRight","debounce","timespan","timeoutID","context","debounced","clearTimeout","setTimeout","flip","getArgAt","invokerOn","target","methodName","method","type","invoker","boundArgs","mapArgs","mapper","tapArgs","readers","throttle","lastCall","now","Date","unary","adapter","allOf","predicates","anyOf","some","condition","trueFn","falseFn","applyArgsTo","applyArgs","is","isGT","isGTE","isLT","isLTE","add","n","max","divide","generate","limit","modulo","multiply","randomInt","random","range","step","ceil","remainder","subtract","_immutable","obj","indexOf","freeze","getOwnPropertyNames","isNull","_isEnumerable","enumerables","_keyToPair","_merge","getKeys","source","_setPathIn","parts","setter","headAsInt","parseInt","v","setIn","checker","message","keyPaths","pathSeparator","getValues","getPathIn","keys","fromPairs","pairsList","pair","getIn","getPath","path","separator","split","has","immutable","make","values","valuesLen","pick","whitelist","pickIf","setKey","setPath","setPathIn","skip","blacklist","skipIf","updateIn","updateKey","validate","checkers","errors","_getPadding","char","repeat","padLeft","padRight","testWith","pattern","_reProto","test","bind","isType","typeName","_objectProto","toString","replace","lamb","create","_version","prototype","RegExp","generic","Function","reduceRight","drop","dropN","head","init","last","tail","take","takeN","union","zip","zipWithIndex","sorter","sorterDesc","pipe","wrap","isNot","_pairsFrom","_tearFrom","_valuesFrom","hasKey","hasKeyValue","hasOwn","hasOwnProperty","hasOwnKey","merge","mergeOwn","ownPairs","ownValues","pairs","tear","tearOwn","validateWith","isNil","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.22.0\n * @module lamb\n * @license MIT\n * @preserve\n */\n!function (host) {\n \"use strict\";\n\n var lamb = Object.create(null);\n\n /**\n * The current module version.\n * @memberof module:lamb\n * @private\n * @category Core\n * @type String\n */\n lamb._version = \"0.22.0\";\n\n // alias used as a placeholder argument for partial application\n var _ = lamb;\n\n // some prototype shortcuts for internal use\n var _arrayProto = Array.prototype;\n var _objectProto = Object.prototype;\n var _reProto = RegExp.prototype;\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 Core\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\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 getName = _.getKey(\"name\");\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, getName);\n *\n * users.map(sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @param {...Function} fn\n * @returns {Function}\n */\n function compose () {\n var functions = arguments;\n\n return function () {\n var args = arguments;\n var len = functions.length;\n\n while (len--) {\n args = [functions[len].apply(this, args)];\n }\n\n return args[0];\n };\n }\n\n /**\n * Creates generic functions out of methods.\n * @memberof module:lamb\n * @category Core\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}. Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @function\n * @example\n * // Lamb's \"filter\" is actually implemented like this\n * var filter = _.generic(Array.prototype.filter);\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 * @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 Core\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\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 used as a placeholder argument:\n * it's useful to alias it as _ or __.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n * var parseInt10 = _.partial(parseInt, _, 10);\n *\n * weights.map(parseInt10) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {...*} args\n * @returns {Function}\n */\n function partial (fn) {\n var args = slice(arguments, 1);\n\n return function () {\n var lastArgumentIdx = 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] = boundArg === _ ? arguments[lastArgumentIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastArgumentIdx < len; lastArgumentIdx++) {\n newArgs.push(arguments[lastArgumentIdx]);\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\n\n /**\n * Builds an array comprised of all values of the array-like object passing the predicate test.
\n * It's a generic version of [Array.prototype.filter]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter}.\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 * @function\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Array}\n */\n var filter = generic(_arrayProto.filter);\n\n /**\n * Executes the provided iteratee for each element of the given array-like object.
\n * It's a generic version of [Array.prototype.forEach]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach}.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment\n * var addClass = function (className) {\n * return function (element) {\n * element.classList.add(className);\n * };\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 * @function\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n */\n var forEach = generic(_arrayProto.forEach);\n\n /**\n * Creates an array from the results of the provided iteratee.
\n * It's a generic version of [Array.prototype.map]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map}.\n * @example\n * function getSquareRoots () {\n * return _.map(arguments, Math.sqrt);\n * }\n *\n * getSquareRoots(4, 9, 16) // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Array}\n */\n var map = generic(_arrayProto.map);\n\n /**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new value using the provided accumulator function.
\n * It's a generic version of [Array.prototype.reduce]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce}.\n * @example\n * _.reduce([1, 2, 3, 4], _.add) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduce = generic(_arrayProto.reduce);\n\n /**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last element instead.
\n * It's a generic version of [Array.prototype.reduceRight]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight}.\n * @memberof module:lamb\n * @category Array\n * @function\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduceRight = generic(_arrayProto.reduceRight);\n\n /**\n * Builds an array by extracting a portion of an array-like object.
\n * It's a generic version of [Array.prototype.slice]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice}.\n * @example\n * _.slice([\"foo\", \"bar\", \"baz\"], 0, 2) // => [\"foo\", \"bar\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} [start=0] - Zero-based index at which to begin extraction.\n * @param {Number} [end=arrayLike.length] - Zero-based index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\n var slice = generic(_arrayProto.slice);\n\n lamb.filter = filter;\n lamb.forEach = forEach;\n lamb.map = map;\n lamb.reduce = reduce;\n lamb.reduceRight = reduceRight;\n lamb.slice = slice;\n\n\n function _findSliceEndIndex (arrayLike, predicate, predicateContext) {\n var idx = -1;\n var len = arrayLike.length;\n\n while (++idx < len && predicate.call(predicateContext, arrayLike[idx], idx, arrayLike));\n\n return idx;\n }\n\n function _flatten (array, output) {\n array.forEach(function (value) {\n if (Array.isArray(value)) {\n _flatten(value, output);\n } else {\n output.push(value);\n }\n });\n\n return output;\n }\n\n function _getPositiveIndex (index, len) {\n return clamp(index, -len, len - 1) === Math.floor(index) ? index < 0 ? index + len : index : void 0;\n }\n\n function _groupWith (makeValue, startValue) {\n return function (arrayLike, iteratee, iterateeContext) {\n return reduce(arrayLike, function (result, element, idx) {\n var key = iteratee.call(iterateeContext, element, idx, arrayLike);\n var value = makeValue(key in result ? result[key] : startValue , element);\n\n result[key] = value;\n\n return result;\n }, {});\n };\n }\n\n function _setIndex (arrayLike, index, value, updater) {\n var result = slice(arrayLike);\n var idx = _getPositiveIndex(index, arrayLike.length);\n\n if (!isUndefined(idx)) {\n result[idx] = updater ? updater(arrayLike[idx]) : value;\n }\n\n return result;\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.isSVZ|isSVZ}; 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, 0);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @param {*} value\n * @param {Number} [fromIndex=0] The position at which to begin searching for the given value.\n * @returns {Function}\n */\n function contains (value, fromIndex) {\n return function (arrayLike) {\n return isIn(arrayLike, value, fromIndex);\n };\n }\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Object}\n */\n var count = _groupWith(partial(add, 1), 0);\n\n /**\n * Using the provided iteratee, and its optional context, builds a partial application of\n * {@link module:lamb.count|count} 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 * @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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Function}\n */\n function countBy (iteratee, iterateeContext) {\n return partial(count, _, iteratee, iterateeContext);\n }\n\n /**\n * Returns an array of items present only in the first of the given arrays.
\n * Note that since version 0.13.0 this function uses the [\"SameValueZero\" comparison]{@link module:lamb.isSVZ|isSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 4, 5];\n * var a3 = [4, 5, 3, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a1, a2, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @param {Array} array\n * @param {...Array} other\n * @returns {Array}\n */\n function difference (array) {\n var rest = shallowFlatten(slice(arguments, 1));\n var isInRest = partial(isIn, rest, _, 0);\n return array.filter(not(isInRest));\n }\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 * _.drop(arr, 2) // => [3, 4, 5]\n * _.drop(arr, -1) // => [5]\n * _.drop(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropN|dropN}\n * @see {@link module:lamb.take|take}, {@link module:lamb.takeN|takeN}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n var drop = binary(slice);\n\n /**\n * A curried version of {@link module:lamb.drop|drop} 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.drop|drop} about passing a negative n.\n * @example\n * var drop2 = _.dropN(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.take|take}, {@link module:lamb.takeN|takeN}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var dropN = _curry(drop, 2, true);\n\n /**\n * Builds a function that drops the first n elements satisfying a predicate 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.drop|drop}, {@link module:lamb.dropN|dropN}\n * @see {@link module:lamb.take|take}, {@link module:lamb.takeN|takeN}\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function dropWhile (predicate, predicateContext) {\n return function (arrayLike) {\n return slice(arrayLike, _findSliceEndIndex(arrayLike, predicate, predicateContext));\n };\n }\n\n /**\n * Returns a partial application of {@link module:lamb.filter|filter} that uses the given predicate and\n * the optional context 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 * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function filterWith (predicate, predicateContext) {\n return partial(filter, _, predicate, predicateContext);\n }\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {*}\n */\n function find (arrayLike, predicate, predicateContext) {\n var result;\n\n for (var i = 0, len = arrayLike.length, element; i < len; i++) {\n element = arrayLike[i];\n\n if (predicate.call(predicateContext, element, i, arrayLike)) {\n result = element;\n break;\n }\n }\n\n return result;\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Number}\n */\n function findIndex (arrayLike, predicate, predicateContext) {\n var result = -1;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (predicate.call(predicateContext, arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\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 * @function\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Array}\n */\n var flatMap = compose(shallowFlatten, map);\n\n /**\n * Builds a partial application of {@link module:lamb.flatMap|flatMap} using the given iteratee\n * and the optional context. The resulting function expects 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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Function}\n */\n function flatMapWith (iteratee, iterateeContext) {\n return partial(flatMap, _, iteratee, iterateeContext);\n }\n\n /**\n * Flattens an array. See also {@link module:lamb.shallowFlatten|shallowFlatten}.\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 * @param {Array} array\n * @returns {Array}\n */\n function flatten (array) {\n return _flatten(array, []);\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 * @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 * @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 function getAt (index) {\n return function (arrayLike) {\n var idx = _getPositiveIndex(index, arrayLike.length);\n return isUndefined(idx) ? idx : arrayLike[idx];\n };\n }\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Object}\n */\n var group = _groupWith(invoker(\"concat\"), []);\n\n /**\n * Using the provided iteratee, and its optional context, builds a partial application\n * of {@link module:lamb.group|group} 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 * @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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Function}\n */\n function groupBy (iteratee, iterateeContext) {\n return partial(group, _, iteratee, iterateeContext);\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 * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var head = getAt(0);\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Object}\n */\n var index = _groupWith(getArgAt(1));\n\n /**\n * Using the provided iteratee, and its optional context, builds a partial application\n * of {@link module:lamb.index|index} 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 * @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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Function}\n */\n function indexBy (iteratee, iterateeContext) {\n return partial(index, _, iteratee, iterateeContext);\n }\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 * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var init = partial(slice, _, 0, -1);\n\n /**\n * Returns an array of every item present in all given arrays.
\n * Note that since version 0.13.0 this function uses the [\"SameValueZero\" comparison]{@link module:lamb.isSVZ|isSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @param {...Array} array\n * @return {Array}\n */\n function intersection () {\n var rest = slice(arguments, 1);\n return uniques(arguments[0]).filter(function (item) {\n return rest.every(contains(item));\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.isSVZ|isSVZ}; 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, 2, 3) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @param {Number} [fromIndex=0] The position at which to begin searching for the given value.\n * @returns {Boolean}\n */\n function isIn (arrayLike, value, fromIndex) {\n var result = false;\n\n for (var i = fromIndex >>> 0, len = arrayLike.length; i < len; i++) {\n if (isSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n }\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 * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var last = getAt(-1);\n\n /**\n * Generates an array with the values passed as arguments.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @param {...*} value\n * @returns {Array}\n */\n function list () {\n return arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.map|map} using the given iteratee and the optional context.\n * The resulting function expects 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 * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {function}\n */\n function mapWith (iteratee, iterateeContext) {\n return partial(map, _, iteratee, iterateeContext);\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 * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Array, Array<*>>}\n */\n function partition (arrayLike, predicate, predicateContext) {\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.call(predicateContext, el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.partition|partition} using the given predicate and the optional context.\n * The resulting function expects 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 * @see {@link module:lamb.partition|partition}\n * @param {ListIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function partitionWith (predicate, predicateContext) {\n return partial(partition, _, predicate, predicateContext);\n }\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 * @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 * @see {@link module:lamb.pluck|pluck}\n * @function\n * @param {String} key\n * @returns {Function}\n */\n function pluckKey (key) {\n return mapWith(getKey(key));\n }\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 * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function reverse (arrayLike) {\n return slice(arrayLike).reverse();\n }\n\n /**\n * Builds a function that creates a copy of an array-like object with the given\n * index changed to the provided 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 * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\n function setAt (index, value) {\n return function (arrayLike) {\n return _setIndex(arrayLike, index, value);\n };\n }\n\n /**\n * Flattens the \"first level\" of an array.
\n * See also {@link module:lamb.flatten|flatten}.\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 * @param {Array} array\n * @returns {Array}\n */\n function shallowFlatten (array) {\n return _arrayProto.concat.apply([], array);\n }\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 * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var tail = partial(slice, _, 1, void 0);\n\n /**\n * Retrieves the first n elements from an array or array-like object.\n * Note that, being this a partial application 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 * _.take(arr, 3) // => [1, 2, 3]\n * _.take(arr, -1) // => [1, 2, 3, 4]\n * _.take(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeN|takeN}\n * @see {@link module:lamb.drop|drop}, {@link module:lamb.dropN|dropN}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n var take = partial(slice, _, 0, _);\n\n /**\n * A curried version of {@link module:lamb.take|take} 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.take|take} about passing a negative n.\n * @example\n * var take2 = _.takeN(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.take|take}\n * @see {@link module:lamb.drop|drop}, {@link module:lamb.dropN|dropN}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var takeN = _curry(take, 2, true);\n\n /**\n * Builds a function that takes the first n elements satisfying a predicate from 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.take|take}, {@link module:lamb.takeN|takeN}\n * @see {@link module:lamb.drop|drop}, {@link module:lamb.dropN|dropN}\n * @param {ListIteratorCallback} predicate\n * @param {Object} predicateContext\n * @returns {Function}\n */\n function takeWhile (predicate, predicateContext) {\n return function (arrayLike) {\n return slice(arrayLike, 0, _findSliceEndIndex(arrayLike, predicate, predicateContext));\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 * @param {ArrayLike>} arrayLike\n * @returns {Array>}\n */\n function transpose (arrayLike) {\n var result = [];\n var minLen = apply(Math.min, pluck(arrayLike, \"length\")) >>> 0;\n var len = arrayLike.length;\n\n for (var i = 0, j; i < minLen; i++) {\n result.push([]);\n\n for (j = 0; j < len; j++) {\n result[i][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 * @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 * @param {...ArrayLike} arrayLike\n * @returns {Array}\n */\n var union = compose(uniques, flatMapWith(unary(slice)), list);\n\n /**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Can work with lists of complex objects if supplied with an iteratee.
\n * Note that since version 0.13.0 this function uses the [\"SameValueZero\" comparison]{@link module:lamb.isSVZ|isSVZ}.\n * @example with simple values\n * _.uniques([1, 2, 2, 3, 4, 3, 5, 1]) // => [1, 2, 3, 4, 5]\n *\n * @example with complex values\n * var data = [\n * {id: \"1\"},\n * {id: \"4\"},\n * {id: \"5\"},\n * {id: \"1\"},\n * {id: \"5\"},\n * ];\n *\n * _.uniques(data, _.getKey(\"id\")) // => [{id: \"1\"}, {id: \"4\"}, {\"id\": 5}]\n *\n * @memberof module:lamb\n * @category Array\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} [iteratee] Defaults to the [identity function]{@link module:lamb.identity}.\n * @param {Object} [iterateeContext]\n * @returns {Array}\n */\n function uniques (arrayLike, iteratee, iterateeContext) {\n if (typeof iteratee !== \"function\") {\n iteratee = identity;\n }\n\n var result = [];\n var seen = [];\n var value;\n\n for (var i = 0; i < arrayLike.length; i++) {\n value = iteratee.call(iterateeContext, arrayLike[i], i , arrayLike);\n\n if (!isIn(seen, value)) {\n seen.push(value);\n result.push(arrayLike[i]);\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function that creates a copy of an array-like object with the given index changed\n * 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 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\"]\n *\n * @memberof module:lamb\n * @category Array\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 * 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 * See also {@link module:lamb.zipWithIndex|zipWithIndex} and {@link module:lamb.transpose|transpose} for the reverse operation.\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 * @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 * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\n var zipWithIndex = mapWith(binary(list));\n\n lamb.contains = contains;\n lamb.count = count;\n lamb.countBy = countBy;\n lamb.difference = difference;\n lamb.drop = drop;\n lamb.dropN = dropN;\n lamb.dropWhile = dropWhile;\n lamb.filterWith = filterWith;\n lamb.find = find;\n lamb.findIndex = findIndex;\n lamb.flatMap = flatMap;\n lamb.flatMapWith = flatMapWith;\n lamb.flatten = flatten;\n lamb.getAt = getAt;\n lamb.group = group;\n lamb.groupBy = groupBy;\n lamb.head = head;\n lamb.index = index;\n lamb.indexBy = indexBy;\n lamb.init = init;\n lamb.intersection = intersection;\n lamb.isIn = isIn;\n lamb.last = last;\n lamb.list = list;\n lamb.mapWith = mapWith;\n lamb.partition = partition;\n lamb.partitionWith = partitionWith;\n lamb.pluck = pluck;\n lamb.pluckKey = pluckKey;\n lamb.reverse = reverse;\n lamb.setAt = setAt;\n lamb.shallowFlatten = shallowFlatten;\n lamb.tail = tail;\n lamb.take = take;\n lamb.takeN = takeN;\n lamb.takeWhile = takeWhile;\n lamb.transpose = transpose;\n lamb.union = union;\n lamb.uniques = uniques;\n lamb.updateAt = updateAt;\n lamb.zip = zip;\n lamb.zipWithIndex = zipWithIndex;\n\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 if (!isSVZ(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 return result;\n }\n\n function _compareWith (criteria) {\n var len = criteria.length;\n\n return function (a, b) {\n var result = 0;\n var isDescSort;\n var criterion;\n\n for (var i = 0; i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n\n if (result !== 0) {\n isDescSort = criteria[i].isDescending;\n break;\n }\n }\n\n if (result === 0) {\n isDescSort = criteria[len - 1].isDescending;\n result = a.index - b.index;\n }\n\n return isDescSort ? -result : result;\n };\n }\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,\n index: pivot\n }, {\n value: array[pivot],\n 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 function _makeCriteria (sorters) {\n return sorters.length ? sorters.map(_makeCriterion) : [_sorter()];\n }\n\n function _makeCriterion (criterion) {\n return typeof Object(criterion).compare === \"function\" ? criterion : _sorter(criterion);\n }\n\n function _sorter (reader, isDescending, comparer) {\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (typeof reader === \"function\" && reader !== identity) {\n a = reader(a);\n b = reader(b);\n }\n\n return (comparer || _comparer)(a, b);\n }\n };\n }\n\n /**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example with simple values\n * _.insert([], 1) // => [1]\n * _.insert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.insert([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 = _.insert(\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 * @param {Array} array\n * @param {*} element\n * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}] - The sorting criteria used to sort the array.\n * @returns {Array}\n */\n function insert (array, element) {\n var criteria = _makeCriteria(slice(arguments, 2));\n var result = array.concat();\n var idx = _getInsertionIndex(array, element, _compareWith(criteria), 0, array.length);\n\n result.splice(idx, 0, element);\n return result;\n }\n\n /**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted copy of an\n * array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you can also\n * 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 in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type, 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 * @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(slice(arguments, 1));\n var data = [];\n var result = [];\n var len = arrayLike.length;\n\n for (var i = 0; i < len; i++) {\n data.push({\n value: arrayLike[i],\n index: i\n });\n }\n\n data.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result.push(data[i].value);\n }\n\n return result;\n }\n\n /**\n * Creates an ascending sort criterion with the provided reader and 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.insert|insert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a simple value from a complex one. The function should evaluate the array element and supply the 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 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.insert|insert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a simple value from a complex one. The function should evaluate the array element and supply the 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. The returned\n * function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you can also\n * 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 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 * @param {...(Sorter|Function)} [sorter={@link module:lamb.sorter|sorter()}]\n * @returns {Function}\n */\n function sortWith () {\n var sorters = slice(arguments);\n\n return function (arrayLike) {\n return sort.apply(null, [arrayLike].concat(sorters));\n };\n }\n\n lamb.insert = insert;\n lamb.sort = sort;\n lamb.sorter = sorter;\n lamb.sorterDesc = sorterDesc;\n lamb.sortWith = sortWith;\n\n\n function _currier (fn, arity, isRightCurry, slicer, argsHolder) {\n return function () {\n var args = argsHolder.concat(slicer(arguments));\n\n if (args.length >= arity) {\n return fn.apply(this, isRightCurry ? args.reverse() : args);\n } else {\n return _currier(fn, arity, isRightCurry, slicer, args);\n }\n };\n }\n\n function _curry (fn, arity, isRightCurry, isAutoCurry) {\n var slicer = isAutoCurry ? slice : function (a) {\n return a.length ? [a[0]] : [];\n };\n\n if ((arity >>> 0) !== arity) {\n arity = fn.length;\n }\n\n return _currier(fn, arity, isRightCurry, slicer, []);\n }\n\n /**\n * Applies the passed function to the given argument list.\n * @example\n * _.apply(_.add, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\n function apply (fn, args) {\n return fn.apply(fn, slice(args));\n }\n\n /**\n * A curried version of {@link module:lamb.apply|apply}. Expects an array-like object to use as arguments\n * and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyDataTo = _.applyArgs(data);\n *\n * applyDataTo(_.add) // => 7\n * applyDataTo(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @param {ArrayLike} args\n * @returns {Function}\n */\n var applyArgs = _curry(apply, 2, true);\n\n /**\n * Builds a function that passes only the specified amount of arguments to the given function.
\n * See also {@link module:lamb.binary|binary} and {@link module:lamb.unary|unary} for common use\n * cases shortcuts.\n * @example\n * var data = [\"1-2\", \"13-5\", \"6-23\"];\n * var getDashIndex = _.invoker(\"indexOf\", \"-\");\n *\n * data.map(getDashIndex) // => [1, 2, -1]\n * data.map(_.aritize(getDashIndex, 1)) // = > [1, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\n function aritize (fn, arity) {\n return function () {\n return apply(fn, slice(arguments, 0, arity));\n };\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 * See also {@link module:lamb.unary|unary}.\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 * @param {Function} fn\n * @returns {Function}\n */\n function binary (fn) {\n return function (a, b) {\n return fn(a, b);\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 * See also {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * and {@link module:lamb.partial|partial}.\n * @example\n * var multiplyBy = _.curry(_.multiply);\n * var multiplyBy10 = multiplyBy(10);\n *\n * multiplyBy10(5) // => 50\n * multiplyBy10()(5) // => 50\n * multiplyBy10()()(2) // => 20\n *\n * @memberof module:lamb\n * @category Function\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 * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var divideBy = _.curryRight(_.divide);\n * var halve = divideBy(2);\n * halve(3) // => 1.5\n * halve(3, 7) // => 1.5\n *\n * @memberof module:lamb\n * @category Function\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 * 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 * Note that you can pass undefined values as arguments explicitly, if you are so inclined, but empty\n * calls doesn't consume the arity.
\n * See also {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight} and\n * {@link module:lamb.partial|partial}.\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 * @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 * @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 * Returns a function that will execute the given function only if it stops being called for the specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call 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 * @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 context = this;\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(context, args);\n };\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n }\n\n /**\n * Returns a function that applies its arguments to the original function 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 * @param {Function} fn\n * @returns {Function}\n */\n function flip (fn) {\n return function () {\n var args = slice(arguments).reverse();\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 * @param {Number} index\n * @returns {Function}\n */\n function getArgAt (index) {\n return compose(getAt(index), list);\n }\n\n /**\n * Accepts an object and builds a function expecting a method name, and optionally arguments, to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the 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 * @param {Object} target\n * @returns {Function}\n */\n function invokerOn (target) {\n return function (methodName) {\n var args = slice(arguments, 1);\n var method = target[methodName];\n return type(method) === \"Function\" ? method.apply(target, args) : void 0;\n };\n }\n\n /**\n * Builds a function that will invoke the given method name on any received object and return\n * the result. If no method with such name is found the function will return undefined.\n * Along with the method name it's possible to supply some arguments that will be bound to the method call.
\n * Further arguments can also be passed when the function is actually called, and they will be concatenated\n * to the bound ones.
\n * If different objects share a method name it's possible to build polymorphic functions as you can see in\n * the example below.
\n * {@link module:lamb.condition|Condition} can be used to wrap invoker to avoid this behaviour\n * by adding a predicate, while {@link module:lamb.adapter|adapter} can build more complex polymorphic functions\n * without the need of homonymy.
\n * Returning undefined or checking for such value is meant to favor composition and interoperability\n * between the aforementioned functions: for a more standard behaviour see also {@link module:lamb.generic|generic}.\n * See also {@link module:lamb.invokerOn|invokerOn}.\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 * @param {String} methodName\n * @param {...*} [boundArg]\n * @returns {Function}\n */\n function invoker (methodName) {\n var boundArgs = slice(arguments, 1);\n\n return function (target) {\n var args = slice(arguments, 1);\n var method = target[methodName];\n return type(method) === \"Function\" ? method.apply(target, boundArgs.concat(args)) : void 0;\n };\n }\n\n /**\n * Builds a function that allows to map over the received arguments before applying them to the original one.\n * @example\n * var sumArray = _.invoker(\"reduce\", _.add);\n * var sum = _.compose(sumArray, _.list);\n *\n * sum(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, _, 2);\n * var sumSquares = _.mapArgs(sum, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\n function mapArgs (fn, mapper) {\n return compose(partial(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 * See also {@link module:lamb.compose|compose}.\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 * @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(_.add, _.getKey(\"count\"), _.getKey(\"length\"));\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @param {...?Function} [tapper]\n * @returns {Function}\n */\n function tapArgs (fn) {\n var readers = slice(arguments, 1);\n\n return function () {\n var len = arguments.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(readers[i] ? readers[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 {@link module:lamb.debounce|debounce}\n * 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 * @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 * See also {@link module:lamb.binary|binary}.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * weights.map(_.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @param {Function} fn\n * @returns {Function}\n */\n function unary (fn) {\n return function (a) {\n return fn(a);\n };\n }\n\n /**\n * Wraps the function fn inside a wrapper function.
\n * This allows to conditionally execute fn, to tamper with its arguments or return value\n * and to run code before and after its execution.
\n * Being this nothing more than a \"{@link module:lamb.flip|flipped}\" [partial application]{@link module:lamb.partial},\n * you can also easily build new functions from existent ones.\n * @example\n * var arrayMax = _.wrap(Math.max, _.apply);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @param {Function} fn\n * @param {Function} wrapper\n * @returns {Function}\n */\n var wrap = binary(flip(partial));\n\n lamb.apply = apply;\n lamb.applyArgs = applyArgs;\n lamb.aritize = aritize;\n lamb.binary = binary;\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.invokerOn = invokerOn;\n lamb.invoker = invoker;\n lamb.mapArgs = mapArgs;\n lamb.pipe = pipe;\n lamb.tapArgs = tapArgs;\n lamb.throttle = throttle;\n lamb.unary = unary;\n lamb.wrap = wrap;\n\n\n /**\n * Accepts a series of functions and builds a function that applies the received arguments to each one and\n * returns the first non-undefined value.
\n * Meant to work in sinergy with {@link module:lamb.condition|condition} and {@link module:lamb.invoker|invoker},\n * can be useful as a strategy pattern for functions, to mimic conditional logic 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 * _.condition(_.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 * @param {...Function} fn\n * @returns {Function}\n */\n function adapter () {\n var functions = slice(arguments);\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = apply(functions[i], arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n }\n\n /**\n * Builds a predicate that returns true if all the given predicates are satisfied.\n * The arguments passed to the resulting function are applied to every predicate unless one of them returns false.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositive = function (n) { return n > 0; };\n * var isPositiveEven = _.allOf(isEven, isPositive);\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 * @param {...Function} predicate\n * @returns {Function}\n */\n function allOf () {\n var predicates = slice(arguments);\n\n return function () {\n var args = arguments;\n\n return predicates.every(function (predicate) {\n return predicate.apply(null, args);\n });\n };\n }\n\n /**\n * Builds a predicate that returns true if at least one of the given predicates is satisfied.\n * The arguments passed to the resulting function are applied to every predicate until one of them returns true.\n * @example\n * // Lamb's \"isNil\" is actually implemented like this\n * var isNil = _.anyOf(_.isNull, _.isUndefined);\n *\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 Logic\n * @see {@link module:lamb.allOf|allOf}\n * @param {...Function} predicate\n * @returns {Function}\n */\n function anyOf () {\n var predicates = slice(arguments);\n\n return function () {\n var args = arguments;\n\n return predicates.some(function (predicate) {\n return predicate.apply(null, args);\n });\n };\n }\n\n /**\n * Builds a function that will apply the received arguments to trueFn, if the predicate is satisfied with\n * the same arguments, or to falseFn otherwise.
\n * If falseFn isn't provided and the predicate isn't satisfied the function will return undefined.
\n * Although you can use other conditions as trueFn or falseFn, it's probably better to\n * use {@link module:lamb.adapter|adapter} to build more complex behaviours.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halve = function (n) { return n / 2; };\n * var halveIfEven = _.condition(isEven, halve, _.identity);\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.invoker|invoker}\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 var applyArgsTo = applyArgs(arguments);\n return applyArgsTo(predicate) ? applyArgsTo(trueFn) : falseFn ? applyArgsTo(falseFn) : void 0;\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, NaN is equal to itself.
\n * See also {@link module:lamb.isSVZ|isSVZ} which performs the check using the \"SameValueZero\" comparison.\n * @example\n * var testObject = {};\n *\n * _.is({}, testObject) // => false\n * _.is(testObject, testObject) // => true\n * _.is(\"foo\", \"foo\") // => true\n * _.is(0, -0) // => false\n * _.is(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see [SameValue comparison]{@link https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero}\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function is (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : isSVZ(a, b);\n }\n\n /**\n * Verifies that the first given value is greater than the second.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.isGT(today, pastDate) // true\n * _.isGT(pastDate, today) // false\n * _.isGT(3, 4) // false\n * _.isGT(3, 3) // false\n * _.isGT(3, 2) // true\n * _.isGT(0, -0) // false\n * _.isGT(-0, 0) // false\n * _.isGT(\"a\", \"A\") // true\n * _.isGT(\"b\", \"a\") // true\n *\n * @memberof module:lamb\n * @category Logic\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function isGT (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 operator, so -0 === 0.\n * @example\n * _.isGTE(3, 4) // false\n * _.isGTE(3, 3) // true\n * _.isGTE(3, 2) // true\n * _.isGTE(0, -0) // true\n * _.isGTE(-0, 0) // true\n *\n * @memberof module:lamb\n * @category Logic\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function isGTE (a, b) {\n return a >= b;\n }\n\n /**\n * Verifies that the first given value is less than the second.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.isLT(today, pastDate) // false\n * _.isLT(pastDate, today) // true\n * _.isLT(3, 4) // true\n * _.isLT(3, 3) // false\n * _.isLT(3, 2) // false\n * _.isLT(0, -0) // false\n * _.isLT(-0, 0) // false\n * _.isLT(\"a\", \"A\") // false\n * _.isLT(\"a\", \"b\") // true\n *\n * @memberof module:lamb\n * @category Logic\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function isLT (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 operator, so -0 === 0.\n * @example\n * _.isLTE(3, 4) // true\n * _.isLTE(3, 3) // true\n * _.isLTE(3, 2) // false\n * _.isLTE(0, -0) // true\n * _.isLTE(-0, 0) // true\n *\n * @memberof module:lamb\n * @category Logic\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function isLTE (a, b) {\n return a <= b;\n }\n\n /**\n * A simple negation of {@link module:lamb.is|is}, exposed for convenience.\n * @example\n * _.isNot(\"foo\", \"foo\") // => false\n * _.isNot(0, -0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @param {*} valueA\n * @param {*} valueB\n * @returns {Boolean}\n */\n var isNot = not(is);\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 too.
\n * See also {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.isSVZ({}, testObject) // => false\n * _.isSVZ(testObject, testObject) // => true\n * _.isSVZ(\"foo\", \"foo\") // => true\n * _.isSVZ(0, -0) // => true\n * _.isSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see [SameValue comparison]{@link https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero}\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function isSVZ (a, b) {\n return a !== a ? b !== b : 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 * @param {Function} predicate\n * @returns {Function}\n */\n function not (predicate) {\n return function () {\n return !predicate.apply(null, arguments);\n };\n }\n\n lamb.adapter = adapter;\n lamb.allOf = allOf;\n lamb.anyOf = anyOf;\n lamb.condition = condition;\n lamb.is = is;\n lamb.isGT = isGT;\n lamb.isGTE = isGTE;\n lamb.isLT = isLT;\n lamb.isLTE = isLTE;\n lamb.isNot = isNot;\n lamb.isSVZ = isSVZ;\n lamb.not = not;\n\n\n /**\n * Adds two numbers.\n * @example\n * _.add(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function add (a, b) {\n return a + b;\n }\n\n /**\n * \"Clamps\" a number within the given limits.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function clamp (n, min, max) {\n return n < min ? min : n > max ? max : n;\n }\n\n /**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\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 * 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 * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @param {Object} [iterateeContext]\n * @returns {Array}\n */\n function generate (start, len, iteratee, iterateeContext) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee.call(iterateeContext, result[i], i, result));\n }\n\n return result;\n }\n\n /**\n * Performs the modulo operation and should not be confused with the {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not a truncated one, hence the sign of\n * the dividend is not kept, unlike the {@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 http://en.wikipedia.org/wiki/Modulo_operation}\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 * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function multiply (a, b) {\n return a * b;\n }\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 * @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(2, 10, 0) // => [2]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(1, -10, 2) // => [1]\n *\n * @memberof module:lamb\n * @category Math\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\n function range (start, limit, step) {\n if (step === 0 || arguments.length < 2) {\n return [start];\n }\n\n if (!step) {\n step = 1;\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n return generate(start, len, partial(add, step));\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 http://en.wikipedia.org/wiki/Modulo_operation}\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 * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function subtract (a, b) {\n return a - b;\n }\n\n lamb.add = add;\n lamb.clamp = clamp;\n lamb.divide = divide;\n lamb.generate = generate;\n lamb.modulo = modulo;\n lamb.multiply = multiply;\n lamb.randomInt = randomInt;\n lamb.range = range;\n lamb.remainder = remainder;\n lamb.subtract = subtract;\n\n\n function _immutable (obj, seen) {\n if (seen.indexOf(obj) === -1) {\n seen.push(Object.freeze(obj));\n\n Object.getOwnPropertyNames(obj).forEach(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 function _isEnumerable (obj, key) {\n return key in Object(obj) && isIn(enumerables(obj), key);\n }\n\n function _keyToPair (key) {\n return [key, this[key]];\n }\n\n function _merge (getKeys) {\n return reduce(slice(arguments, 1), function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n }\n\n var _pairsFrom = _curry(function (getKeys, obj) {\n return getKeys(obj).map(_keyToPair, obj);\n });\n\n function _setPathIn (obj, parts, value) {\n var headAsInt = parseInt(parts[0], 10);\n var target;\n var setter;\n\n if (Array.isArray(obj) && headAsInt == parts[0]) {\n target = getAt(headAsInt)(obj);\n setter = function (v) {\n return setAt(headAsInt, v)(obj);\n };\n } else {\n target = (obj || {})[parts[0]];\n setter = partial(setIn, obj, parts[0]);\n }\n\n return setter(\n parts.length < 2 ? value : _setPathIn(target, parts.slice(1), value)\n );\n }\n\n var _tearFrom = _curry(function (getKeys, obj) {\n return getKeys(obj).reduce(function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n return result;\n }, [[], []]);\n });\n\n var _valuesFrom = _curry(function (getKeys, obj) {\n return getKeys(obj).map(partial(getIn, obj));\n });\n\n /**\n * Builds a checker function meant to be used with {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to compare their values. In\n * other words all the received keyPaths will be passed as arguments to the predicate\n * 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 * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of property names, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Array} An error in the form [\"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 return predicate.apply(obj, keyPaths.map(getValues)) ? [] : [message, keyPaths];\n };\n }\n\n /**\n * Creates an array with all the enumerable properties of the given object.\n * @example showing the difference with Object.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 * Object.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @see [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * @param {Object} obj\n * @returns {String[]}\n */\n function enumerables (obj) {\n var keys = [];\n\n for (var key in obj) {\n keys.push(key);\n }\n\n return keys;\n }\n\n /**\n * Builds an object from a list of key / value pairs like the one\n * returned by [pairs]{@link module:lamb.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 * @param {Array>} pairsList\n * @returns {Object}\n */\n function fromPairs (pairsList) {\n var result = {};\n\n pairsList.forEach(function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n }\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 * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\n function getIn (obj, key) {\n return obj[key];\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 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 * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @function\n * @param {String} key\n * @returns {Function}\n */\n var getKey = _curry(getIn, 2, 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 * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function getPath (path, separator) {\n return partial(getPathIn, _, path, separator);\n }\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 * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * // same as _.getIn if no path is involved\n * _.getPathIn(user, \"name\") // => \"John\"\n *\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 * @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 * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\n function getPathIn (obj, path, separator) {\n return path.split(separator || \".\").reduce(tapArgs(getIn, Object), obj);\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 * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function has (obj, key) {\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 * @param {String} key\n * @returns {Function}\n */\n var hasKey = _curry(has, 2, true);\n\n /**\n * Builds a function expecting an object to check against the given key / value pair.\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 * @function\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n var hasKeyValue = function (key, value) {\n return compose(partial(is, value), getKey(key));\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 * @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 * @param {String} key\n * @returns {Function}\n */\n var hasOwnKey = _curry(hasOwn, 2, true);\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 * @param {Object} obj\n * @returns {Object}\n */\n function immutable (obj) {\n return _immutable(obj, []);\n }\n\n /**\n * Builds an object from the two given lists, using the first one as keys and the last one as values.
\n * If the list of keys is longer than the values one, the keys will be created with undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.
\n * See also {@link module:lamb.tear|tear} and {@link module:lamb.tearOwn|tearOwn} for the reverse operation.\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 * @param {String[]} keys\n * @param {Array} values\n * @returns {Object}\n */\n function make (keys, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = keys.length; i < len; i++) {\n result[keys[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n }\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 * See also {@link module:lamb.mergeOwn|mergeOwn} for merging only own properties of\n * the given sources.\n * @example\n * _.merge({a: 1}, {b: 3, c: 4}, {b: 5}) // => {a: 1, b: 5, c: 4}\n *\n * @example Arrays or 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 value will be treated as an empty object:\n * _.merge({a: 2}, null, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\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 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 Arrays or 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 value will be treated as an empty object:\n * _.mergeOwn({a: 2}, null, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @param {...Object} source\n * @returns {Object}\n */\n var mergeOwn = partial(_merge, compose(Object.keys, Object));\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 * @param {Object} obj\n * @returns {Array>}\n */\n var ownPairs = _pairsFrom(Object.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 * @param {Object} obj\n * @returns {Array}\n */\n var ownValues = _valuesFrom(Object.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 * @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}\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\n function pick (source, whitelist) {\n var result = {};\n\n whitelist.forEach(function (key) {\n if (key in source) {\n result[key] = source[key];\n }\n });\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose properties will be checked 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}\n * @param {ObjectIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function pickIf (predicate, predicateContext) {\n return function (source) {\n var result = {};\n\n for (var key in source) {\n if (predicate.call(predicateContext, source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n }\n\n /**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the enumerable keys of the source object will be simply copied to an empty\n * 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 * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function setIn (source, key, value) {\n return _merge(enumerables, source, make([key], [value]));\n }\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 * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n function setKey (key, value) {\n return partial(setIn, _, key, value);\n }\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 * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function setPath (path, value, separator) {\n return partial(setPathIn, _, path, value, separator);\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 * 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 * @param {Object|Array} obj\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function setPathIn (obj, path, value, separator) {\n return _setPathIn(obj, path.split(separator || \".\"), value);\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.skipIf|skipIf}\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\n function skip (source, blacklist) {\n var result = {};\n\n for (var key in source) {\n if (blacklist.indexOf(key) === -1) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose properties will be checked 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 * @see {@link module:lamb.skip|skip}\n * @param {ObjectIteratorCallback} predicate\n * @param {Object} [predicateContext]\n * @returns {Function}\n */\n function skipIf (predicate, predicateContext) {\n return pickIf(not(predicate), predicateContext);\n }\n\n /**\n * Tears an object apart by transforming it in an array of two lists: one containing its enumerable keys,\n * the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source object will be unharmed.
\n * See also {@link module:lamb.tearOwn|tearOwn} for picking only the own enumerable properties and\n * {@link module:lamb.make|make} for the reverse operation.\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 * @param {Object} obj\n * @returns {Array, 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 taken into account.
\n * See also {@link module:lamb.make|make} for the reverse operation.\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 * @param {Object} obj\n * @returns {Array, Array<*>>}\n */\n var tearOwn = _tearFrom(Object.keys);\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 * var increment = _.partial(_.add, 1);\n *\n * _.updateIn(user, \"visits\", increment) // => {name: \"John\", visits: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateKey|updateKey}\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) ? setIn(source, key, updater(source[key])) : _merge(enumerables, source);\n }\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 * @example\n * var user = {name: \"John\", visits: 2};\n * var increment = _.partial(_.add, 1);\n * var incrementVisits = _.updateKey(\"visits\", increment);\n *\n * incrementVisits(user) // => {name: \"John\", visits: 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateIn|updateIn}\n * @param {String} key\n * @param {Function} updater\n * @returns {Function}\n */\n function updateKey (key, updater) {\n return partial(updateIn, _, key, updater);\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 isAdult = function (age) { return age >= 18; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(isAdult, \"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) // => [[\"Surname is required\", [\"surname\"]], [\"Must be at least 18 years old\", [\"age\"]]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by {@link module:lamb.checker|checker}, or an empty array.\n */\n function validate (obj, checkers) {\n return checkers.reduce(function (errors, checker) {\n var result = checker(obj);\n result.length && errors.push(result);\n return errors;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of {@link module:lamb.checker|checkers} and\n * returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var isAdult = function (age) { return age >= 18; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(isAdult, \"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) // => [[\"Surname is required\", [\"surname\"]], [\"Must be at least 18 years old\", [\"age\"]]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @function\n * @param {Function[]} checkers\n * @returns {Function}\n */\n var validateWith = _curry(validate, 2, true);\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} for picking only 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 * @param {Object} obj\n * @returns {Array}\n */\n var values = _valuesFrom(enumerables);\n\n lamb.checker = checker;\n lamb.enumerables = enumerables;\n lamb.fromPairs = fromPairs;\n lamb.getIn = getIn;\n lamb.getKey = getKey;\n lamb.getPath = getPath;\n lamb.getPathIn = getPathIn;\n lamb.has = has;\n lamb.hasKey = hasKey;\n lamb.hasKeyValue = hasKeyValue;\n lamb.hasOwn = hasOwn;\n lamb.hasOwnKey = hasOwnKey;\n lamb.immutable = immutable;\n lamb.make = make;\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.setIn = setIn;\n lamb.setKey = setKey;\n lamb.setPath = setPath;\n lamb.setPathIn = setPathIn;\n lamb.skip = skip;\n lamb.skipIf = skipIf;\n lamb.tear = tear;\n lamb.tearOwn = tearOwn;\n lamb.updateIn = updateIn;\n lamb.updateKey = updateKey;\n lamb.validate = validate;\n lamb.validateWith = validateWith;\n lamb.values = values;\n\n\n function _getPadding (source, char, len) {\n return repeat(char[0] || \" \", Math.ceil(len - source.length));\n }\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 * @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 * @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 [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 count is negative, 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 * @param {String} source\n * @param {Number} count\n * @returns {String}\n */\n function repeat (source, count) {\n var result = \"\";\n\n for (var i = 0; i < count; i++) {\n result += source;\n }\n\n return result;\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 * @param {RegExp} pattern\n * @returns {Function}\n */\n function testWith (pattern) {\n return _reProto.test.bind(pattern);\n }\n\n lamb.padLeft = padLeft;\n lamb.padRight = padRight;\n lamb.repeat = repeat;\n lamb.testWith = testWith;\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} and {@link module:lamb.isNull|isUndefined} for individual checks.\n * @function\n * @param {*} value\n * @returns {Boolean}\n */\n var isNil = anyOf(isNull, isUndefined);\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 * @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 * @param {String} typeTag\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 * @param {*} value\n * @returns {Boolean}\n */\n function isUndefined (value) {\n // using void because undefined could be theoretically shadowed\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 * @param {*} value\n * @returns {String}\n */\n function type (value) {\n return _objectProto.toString.call(value).replace(/^\\[\\w+\\s+|\\]$/g, \"\");\n }\n\n lamb.isNil = isNil;\n lamb.isNull = isNull;\n lamb.isType = isType;\n lamb.isUndefined = isUndefined;\n lamb.type = type;\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() { return lamb; });\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 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 * Represent a sorting criteria used by {@link module:lamb.insert|insert}, {@link module:lamb.sort|sort} and {@link module:lamb.sortWith|sortWith},\n * and it's 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"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/package.json b/package.json index 5b4bfb0..f5a0af9 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "coveralls": "gulp coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" }, "tonicExample": "var _ = require('lamb');", - "version": "0.21.0", + "version": "0.22.0", "devDependencies": { "coveralls": "^2.11.8", "gulp": "^3.9.1", diff --git a/src/logic.js b/src/logic.js index 9103200..2e39960 100644 --- a/src/logic.js +++ b/src/logic.js @@ -1,7 +1,7 @@ /** * Accepts a series of functions and builds a function that applies the received arguments to each one and - * returns the first non undefined value.
+ * returns the first non-undefined value.
* Meant to work in sinergy with {@link module:lamb.condition|condition} and {@link module:lamb.invoker|invoker}, * can be useful as a strategy pattern for functions, to mimic conditional logic and also to build polymorphic functions. * @example diff --git a/src/object.js b/src/object.js index 240796a..649a367 100644 --- a/src/object.js +++ b/src/object.js @@ -694,7 +694,7 @@ function setPath (path, value, separator) { * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects), * which will be delegated to {@link module:lamb.setIn|setIn}.
* As a result of that, array-like objects will be converted to objects having numbers as keys - * and paths targeting non object values will be converted to empty objects.
+ * and paths targeting non-object values will be converted to empty objects.
* Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can * use custom path separators. * @example diff --git a/test/spec/arraySpec.js b/test/spec/arraySpec.js index c9da5a2..bdd4e96 100644 --- a/test/spec/arraySpec.js +++ b/test/spec/arraySpec.js @@ -144,7 +144,7 @@ describe("lamb.array", function () { }); describe("flatMap / flatMapWith", function () { - it("should behave like map if the mapping function returns a non array value", function () { + it("should behave like map if the mapping function returns a non-array value", function () { var double = function (n) { return n * 2; }; var arr = [1, 2, 3, 4, 5]; var result = [2, 4, 6, 8, 10]; @@ -208,7 +208,7 @@ describe("lamb.array", function () { expect(lamb.flatMapWith(toUpperCase)(testString)).toEqual(result); }); - it("should return an empty array if is supplied with a non array value", function () { + it("should return an empty array if is supplied with a non-array value", function () { expect(lamb.flatMap({}, lamb.identity)).toEqual([]); expect(lamb.flatMapWith(lamb.identity)({})).toEqual([]); }); diff --git a/test/spec/logicSpec.js b/test/spec/logicSpec.js index c86ce50..8d8564f 100644 --- a/test/spec/logicSpec.js +++ b/test/spec/logicSpec.js @@ -6,7 +6,7 @@ describe("lamb.logic", function () { var isLessThanTen = function (n) { return n < 10; }; describe("adapter", function () { - it("should accept a series of functions and build another function that calls them one by one until a non undefined value is returned", function () { + it("should accept a series of functions and build another function that calls them one by one until a non-undefined value is returned", function () { var isEven = function (n) { return n % 2 === 0; }; var filterString = lamb.condition( lamb.isType("String"), diff --git a/test/spec/objectSpec.js b/test/spec/objectSpec.js index 1b47f6e..dcf91d4 100644 --- a/test/spec/objectSpec.js +++ b/test/spec/objectSpec.js @@ -12,7 +12,7 @@ describe("lamb.object", function () { expect(lamb.enumerables(foo)).toEqual(["d", "a"]); }); - it("should consider non object values as empty objects", function () { + it("should consider non-object values as empty objects", function () { expect( [/foo/, 1, function () {}, null, NaN, void 0, true, new Date()].map(lamb.enumerables) ).toEqual([[], [], [], [], [], [], [], []]); @@ -28,7 +28,7 @@ describe("lamb.object", function () { expect(lamb.fromPairs([["a", 1], ["b", 2], ["a", 3]])).toEqual({a: 3, b: 2}); }); - it("should convert missing or non string keys to strings and missing values to `undefined`", function () { + it("should convert missing or non-string keys to strings and missing values to `undefined`", function () { expect(lamb.fromPairs([[1], [void 0, 2], [null, 3]])).toEqual({"1": void 0, "undefined": 2, "null": 3}); }); }); @@ -76,7 +76,7 @@ describe("lamb.object", function () { expect(lamb.getPathIn(obj, "c.d/e.f", "/")).toBe(6); }); - it("should return undefined for any non existent path", function () { + it("should return undefined for any non-existent path", function () { expect(lamb.getPath("b.a.z")(obj)).toBeUndefined(); expect(lamb.getPathIn(obj, "b.a.z")).toBeUndefined(); expect(lamb.getPath("b.z.a")(obj)).toBeUndefined(); @@ -223,7 +223,7 @@ describe("lamb.object", function () { expect(lamb.make(["a", "b"], [1, 2, 3])).toEqual({a: 1, b: 2}); }); - it("should convert non string keys to strings", function () { + it("should convert non-string keys to strings", function () { expect(lamb.make([null, void 0, 2], [1, 2, 3])).toEqual({"null": 1, "undefined": 2, "2": 3}); }); }); @@ -498,7 +498,7 @@ describe("lamb.object", function () { expect(newObjC).toEqual({"0": 1}); }); - it("should not allow to update a non enumerable property, and return a copy of the source instead, as with non existent keys", function () { + it("should not allow to update a non-enumerable property, and return a copy of the source instead, as with non-existent keys", function () { var newObjA = lamb.updateIn(foo, "z", lamb.always(99)); var newObjB = lamb.updateKey("z", lamb.always(99))(foo); @@ -575,7 +575,7 @@ describe("lamb.object", function () { expect(lamb.setPathIn(obj, "c.d->e.f", 99, "->")).toEqual(r); }); - it("should add non existent properties to existing objects", function () { + it("should add non-existent properties to existing objects", function () { var r1 = lamb.setPath("b.z", 99)(obj); var r2 = lamb.setPath("z.a", 99)(obj); var r3 = lamb.setPath("z.a.b", 99)(obj);