{"id":28350944,"url":"https://github.com/edgarberm/pills","last_synced_at":"2025-10-13T08:34:06.362Z","repository":{"id":149159843,"uuid":"95022979","full_name":"edgarberm/pills","owner":"edgarberm","description":"A collection of fun JavaScript functions (ES6) 😎🎉🎈","archived":false,"fork":false,"pushed_at":"2017-07-10T20:44:02.000Z","size":190,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-20T22:39:36.593Z","etag":null,"topics":["functional","functional-js","functional-programming","javascript","pill"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edgarberm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-06-21T16:14:30.000Z","updated_at":"2023-03-04T06:15:04.000Z","dependencies_parsed_at":"2023-08-27T13:16:08.974Z","dependency_job_id":null,"html_url":"https://github.com/edgarberm/pills","commit_stats":null,"previous_names":["edgarberm/pills"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/edgarberm/pills","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edgarberm%2Fpills","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edgarberm%2Fpills/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edgarberm%2Fpills/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edgarberm%2Fpills/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edgarberm","download_url":"https://codeload.github.com/edgarberm/pills/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edgarberm%2Fpills/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279014317,"owners_count":26085492,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["functional","functional-js","functional-programming","javascript","pill"],"created_at":"2025-05-27T22:08:47.228Z","updated_at":"2025-10-13T08:34:06.356Z","avatar_url":"https://github.com/edgarberm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 💊 Pills\n## A collection of fun JavaScript functions (ES6) 😎🎉🎈\n\nImplementation of the most useful and fun JavaScript functions (ES6).\n\nThis repo do not pretend to be another functional  programming (FP) library as Lodash, Underscore or Ramda.\nThese libraries work very fine and are well tested. They also have a very strong community behind them working\nfor a long time. I recommend that you use them!\n\n\n## Index\n\n- [add](#add)\n- [adjust](#adjust)\n- [all](#all)\n- [always](#always)\n- [and](#and)\n- [any](#any)\n- [append](#append)\n- [arity](#arity)\n- [assoc](#assoc)\n- [assocPath](#assocpath)\n- [camelCase](#camelcase)\n- [capitalize](#capitalize)\n- [chunk](#chunk)\n- [clean](#clean)\n- [compose](#compose)\n- [concat](#concat)\n- [contains](#contains)\n- [curry](#curry)\n- [debounce](#debounce)\n- [defer](#defer)\n- [delay](#delay)\n- [difference](#difference)\n- [dissoc](#dissoc)\n- [dissocPath](#dissocpath)\n- [divide](#divide)\n- [drop](#drop)\n- [evolve](#evolve)\n- [falsy](#falsy)\n- [filterObject](#filterobject)\n- [has](#has)\n- [hasIn](#hasin)\n- [isArray](#isarray)\n- [isEven](#iseven)\n- isEmpty\n- [isFunction](#isfunction)\n- [isInteger](#isinteger)\n- [isNil](#isnil)\n- [isNumber](#isnumber)\n- [isObject](#isobject)\n- isRegExp\n- [isString](#isstring)\n- [mapObject](#mapobject)\n- [match](#match)\n- [max](#max)\n- [mean](#mean)\n- [median](#median)\n- [memoize](#memoize)\n- [merge](#merge)\n- [min](#min)\n- [modulo](#modulo)\n- [multiply](#multiply)\n- [negate](#negate)\n- [none](#none)\n- [not](#not)\n- [nth](#nth)\n- [omit](#omit)\n- [or](#or)\n- [pairs](#pairs)\n- [path](#path)\n- pathOr\n- [percent](#percent)\n- [pick](#pick)\n- [pipe](#pipe)\n- [pluck](#pluck)\n- [prop](#prop)\n- [propOr](#propor)\n- [randomBetween](#randombetween)\n- [reject](#reject)\n- [remove](#remove)\n- [repeat](#repeat)\n- [replace](#replace)\n- [reverse](#reverse)\n- [sort](#sort)\n- [sortBy](#sortby)\n- [square](#square)\n- [subtract](#subtract)\n- [sum](#sum)\n- [take](#take)\n- [throttle](#throttle)\n- [times](#times)\n- [truncate](#truncate)\n- [uniq](#uniq)\n- [uniqBy](#uniqby)\n- [update](#update)\n- [when](#when)\n\n\n---\n\n## Documentation\n\nPlease review the documentation.\n\n\n### add\n\nAdds two values.\n\n```javascript\nadd(2, 4)  // 6\nadd(5, 5)  // 10\nadd('5', 5)  // 10\nadd('5', '5')  // 10\n\ncurry(add)(2)(4)  // 6\n\nconst add2 = curry(add, 2)\nadd2(4)  // 6\n\nconst add2 = n =\u003e add(2, n)\nadd2(4)  // 6\n```\n\n\n### adjust\n\nApplies a function to the value that is in the specified index and returns\na new array with the index element replaced by the result of the function.\n\n```javascript\nadjust(squared, 1, [1, 2, 3])  // [1, 4, 3]\n```\n\n\n### all\n\nReturns `true` if all elements of the list match with the predicate, `false` otherwise.\n\n```javascript\nconst list = [0, 1, 2, 3]\nconst list2 = [11, 12, 13, 14]\nconst bigger10 = n =\u003e n \u003e 10\n\nall(bigger10, list)  // false\nall(bigger10, list2)  // true\n```\n\n\n### always\n\nReturns a function that always returns the given value.\n\nRamda docs says:\nNote that for non-primitives the value returned is a reference to the original value.\nThis function is known as `const`, `constant`, or `K` (for K combinator) in\nother languages and libraries.\n\n```javascript\nconst t = always('lol')\nt()  // \"lol\"\n```\n\n\n### and\n\nReturns `true` if both arguments are `true`; `false` otherwise.\n\n```javascript\nand(true, true)  // true\nand(true, false)  // false\nand(false, false)  // false\nand(false, false)  // false\n```\n\n\n### any\n\nReturns `true` if at least one of elements of the list match the predicate,\n`false` otherwise.\n\n```javascript\nconst list = [0, 1, 2, 3]\nconst list2 = [11, 2, 3, 14]\nconst bigger10 = n =\u003e n \u003e 10\n\nany(bigger10, list)  // false\nany(bigger10, list2)  // true\n```\n\n\n### append\n\nReturns a new list containing the contents of the given list, followed by\nthe given element.\n\n```javascript\nappend('code', ['read', 'write'])  // ['read', 'write', 'code']\nappend('code', [])  // ['code']\nappend(['code'], ['read', 'write'])  // ['read', 'write', ['code']]\n```\n\n\n### arity\n\nReturns the number of arguments accepted by the given function `fn`.\n\n```javascript\nconst foo = (a, b, c) =\u003e a + b + c\nconst bar = (a, {}) =\u003e { a: a }\narity(foo)  // 3\narity(bar)  // 2\n```\n\n\n### assoc\n\nReturns a copy of an object, setting or overriding the specified\nproperty with the given value.\n\nNote that this copies and flattens prototype properties onto the new object as\nwell. All non-primitive properties are copied by reference.\n\n```javascript\nassoc('c', 3, { a: 1, b: 2 })  // { a: 1, b: 2, c: 3 }\nassoc('b', 23, { a: 1, b: 2 })  // { a: 1, b: 23 }\nassoc('unit_price', '€', product)  // { \"brand\": \"Brand goes here!\", ..., \"unit_price\": \"€\", \"width\": 965 }\n```\n\n\n### assocPath\n\nReturns a clone of an object, setting or overriding the nodes required\nto create the given path, and placing the specific value at the tail end of\nthat path.\n\nNote that this copies and flattens prototype properties onto the new object as well.\nAll non-primitive properties are copied by reference.\n\n```javascript\nconst ob = { a: { b: { c: 0 } } }\nconst updated = assocPath(['a', 'b', 'c'], 1, ob)\nconsole.log(updated)  // { a: { b: { c: 1 } } }\nassocPath(['a', 'b', 'c'], 1, ob)  // { a: { b: { c: 1 } } }\nassocPath(['a', 'b'], 1, { a: 5 })  // { a: { b: { c: 1 } } }\n```\n\n\n### camelCase\n\nConverts `string` to camel case style.\nSee [camel case](https://en.wikipedia.org/wiki/CamelCase).\n\n```javascript\nlet baz = 'foo bar'\nlet camel = camelCase(baz)\nconsole.log(camel)  // \"fooBar\"\ncamelCase('foo bar')  // \"fooBar\"\ncamelCase('FOO BAR')  // \"fooBar\"\ncamelCase('x nN foo bar')  // \"xNnFooBar\"\ncamelCase('!--foo-¿?-bar--121-**%')  // \"fooBar121\"\n```\n\n\n### capitalize\n\nConverts the String parameter to lowercase and his first char to uppercase.\n\n```javascript\ncapitalize('lorem ipsum dolor sit amet')  // \"Lorem ipsum dolor sit amet\"\ncapitalize('LOREM IPSUM DOLOR SIT AMET')  // \"Lorem ipsum dolor sit amet\"\n```\n\n\n### chunk\n\nCreates an `array` of elements split into groups the length of `size`.\nIf `array` can't be split evenly, the final chunk will be the remaining\nelements.\n\n```javascript\nchunk(1, ['a', 'b', 'c', 'd'])  // [[\"a\"], [\"b\"], [\"c\"], [\"d\"]]\nchunk(2, ['a', 'b', 'c', 'd'])  // [[\"a\" ,\"b\"], [\"c\", \"d\"]]\nchunk(3, ['a', 'b', 'c', 'd'])  // [[\"a\", \"b\", \"c\"], [\"d\"]]\n```\n\n\n### clean\n\nCreates an array with all `falsy` values removed.\nSee [falsy](#falsy).\n\n```javascript\nconst arr = [0, 1, false, null, undefined, 2, '', 3, '4', NaN]\nconst cln = clean(arr)  // [1, 2, 3, \"4\"]\n```\n\n\n### compose\n\nReturns a function that is the composition of a list of functions, each\nconsuming the return value of the function that follows.\n\nNote that this is exactly the same as [pipe](#pipe) but with the functions in\nopposite order.\n\n```javascript\nconst classyGreeting = (firstName, lastName) =\u003e \"THE NAME'S \" + lastName + \", \" + firstName + \" \" + lastName\nconst yellGreeting = compose(camelCase, classyGreeting)\nyellGreeting('JAMES', 'BOND')  // \"theNameSBondJamesBond\"\n```\n\n\n### concat\n\nReturns the result of concatenating the given lists or strings.\n\n```javascript\nconcat('ABC', 'DEF')  // \"ABCDEF\"\nconcat([1, 2, 3], [4, 5, 6])  // [1, 2, 3, 4, 5, 6]\nconcat('', '')  // \"\"\nconcat([], [])  // []\nconcat({}, '123')  // TypeError: [object Object] does not have a method named \"concat\"\n```\n\n\n### contains\n\nReturns `true` if the specified value is equal to at least one element of the\ngiven list, `false` otherwise.\n\n```javascript\ncontains(3, [1, 2, 3])  // true\ncontains(4, [1, 2, 3])  // false\ncontains(4, [1, 2, 3, 4])  // true\n```\n\n\n### curry\n\nReturns a curried equivalent of the provided function.\n\n```javascript\nconst add5 = curry(add, 5)\nadd5(2)  // 7\nadd5(100)  // 105\n\n// NOTE: In this example curry don't make sense with ES6\nconst add5 = x =\u003e add(5, x)\nadd5(100)  // 105\n```\n\n\n### debounce\n\nLimits the rate at which a function can fire.\n\n```javascript\nconst debouncedResize = debounce((event) =\u003e {\n  console.log('resized')\n}, 1000)\n\nwindow.addEventListener('resize', debouncedResize)\nwindow.addEventListener('resize', debounce(() =\u003e console.log('resizing'), 1000, { inmediate: true }))\n```\n\n\n### defer\n\nDefer a function, scheduling it to run after the current call stack hascleared.\n\n```javascript\ndefer(text =\u003e console.log(text), 'Deferred')\n```\n\n\n### delay\n\nInvokes `fn` after `wait` milliseconds. Any additional arguments are\nprovided to `fn` when it's invoked.\n\n```javascript\ndelay(text =\u003e console.log(text), 1000, 'Text to log after 1000ms')\ndelay(text =\u003e console.log(text), 3000, 'Text to log after 3000ms')\n```\n\n\n### difference\n\nFinds the set (i.e. no duplicates) of all elements in the first list not\ncontained in the second list. Objects and Arrays are compared in terms of\nvalue equality, not reference equality.\n\n```javascript\ndifference([1,2,3,4], [7,6,5,4,3])  // [1, 2]\ndifference([7,6,5,4,3], [1,2,3,4])  // [7, 6, 5]\n```\n\n\n### dissoc\n\nReturns a new object that does not contain a `prop` property.\n\n```javascript\ndissoc('b', { a: 1, b: 2 })  // { a: 1 }\ndissoc('price', product)  // { \"brand\": \"Brand goes here!\", ..., \"width\": 965 }\n```\n\n\n### dissocPath\n\nReturns a copy of the object by omitting the property of the specified path.\n\n```javascript\nconst obj = { a: { b: { c: { d: 100 } } } }\ndissocPath(['a', 'b', 'c', 'd'], obj)  // { a: { b: { c: {} } } }\n```\n\n\n### divide\n\nDivide two numbers.\n\n```javascript\ndivide(10, 2)  // 5\ndivide(100, 2)  // 50\ndivide(1000, 2)  // 500\ndivide(6, 4)  // 1.5\n```\n\n\n### drop\n\nReturns a new array without the `n` elements of the given `list` or string.\n\n```javascript\nconst arr = ['foo', 'bar', 'baz']\ndrop(1, arr)  // [\"bar\", \"baz\"]\ndrop(2, arr)  // [\"baz\"]\ndrop(3, arr)  // []\n```\n\n\n### evolve\n\nReturns a new object according to the transformation functions.\n\n```javascript\nconst product = {\n  \"id\": 66443,\n  \"image\": \"aceb.png\",\n  \"width\": 965,\n  \"height\": 1040,\n  \"description\": \"Description goes here!\",\n  \"categories\": [\"4114\", \"4232\"],\n  \"brand\": \"Brand goes here!\",\n  \"price\": 9.99,\n  \"allergens\": {\n    \"a\": 'Allergen A',\n    \"b\": 'Allergen B'\n  }\n}\n\nconst renameCategory = a =\u003e `000_${ a }`\nconst discount20 = t =\u003e '20% off!! ' + t\nconst restoreRetina = h =\u003e h * 2\nconst applyDiscount20 = p =\u003e p - percent(p, 20)\nconst renameAllergen = t =\u003e `- ${ t }`\n\nconst transformations = {\n  description: discount20,\n  title: discount20,\n  categories: [renameCategory, renameCategory],\n  height: restoreRetina,\n  price: applyDiscount20,\n  allergens: {\n    a: renameAllergen,\n    b:renameAllergen\n  }\n}\n\nevolve(transformations, product)\n// {\n// \"allergens\": Object {\n//   \"a\": \"- Allergen A\",\n//   \"b\": \"- Allergen B\"\n// },\n// \"brand\": \"Brand goes here!\",\n// \"categories\": Object {\n//   \"0\": \"000_4114\",\n//   \"1\": \"000_4232\"\n// },\n// \"description\": \"20% off!! Description goes here!\",\n// \"height\": 2080,\n// \"id\": 66443,\n// \"image\": \"aceb.png\",\n// \"price\": 7.992,\n// \"width\": 965\n// }\n\nfunction Person () {\n  this.name = 'Person'\n  this.age = 36\n  this.height = 196\n}\n\nPerson.prototype.setName = function (name) {\n  return this.name = name\n}\n\nPerson.prototype.greet = function (name) {\n  return `Hi! I'm ${ this.name }. An instance of ${ Person }`\n}\n\n\nconst rename = n =\u003e 'Edgar'\nconst grow = a =\u003e a + 1\nconst transformations2 = {\n  name: rename,\n  age: grow\n}\n\nconst person = new Person()\nperson.setName('Bob')\nconst newPerson = evolve(transformations2, person)\nconsole.log(newPerson)\n// {\n//   \"age\": 37,\n//   \"height\": 196,\n//   \"name\": \"Edgar\"\n// }\n\nconsole.log(person.name)  // Bob\n```\n\n\n### falsy\n\nReturns if a value is falsy or not.\n\nFalsy values:\n- false\n- 0 (zero)\n- \"\" (empty string)\n- null\n- undefined\n- NaN (a special Number value meaning Not-a-Number!)\n\n```javascript\nfalsy(false)  // true\nfalsy(0)  // true\nfalsy('')  // true\nfalsy(null)  // true\nfalsy(undefined)  // true\nfalsy(NaN)  // true\nfalsy(1)  // false\n```\n\n\n### filterObject\n\nIterates over properties of an object `obj` returning an array of all\nelements `fn` (predicate) returns truthy for.\n\nNote that the predicate is invoked with three arguments: `value`, `key`, `object`.\n\n```javascript\nconst object = { 'a': 5, 'b': 8, 'c': 10 }\nfilterObject((n) =\u003e !(n % 5), object)  // [5, 10]\n```\n\n\n### has\n\nReturns whether or not an object has an own property with the specified name.\nA shortcut for Object.hasOwnProperty.\n\nNote that this method is similar as `hasIn` with plain Objects, but he can't\naccess to the prototype properties of the Function objects.\n\n```javascript\nconst product = {\n  \"id\": 66443,\n  \"image\": \"aceb.png\",\n  \"width\": 965,\n  \"height\": 1040,\n  \"description\": \"Description goes here!\",\n  \"categories\": [\"4114\",\"4232\"],\n  \"brand\": \"Brand goes here!\",\n  \"price\": 9.99,\n  \"sub\": {\n    \"a\": 1000,\n    \"b\": 2000\n  }\n}\n\nhas('price', product)  // true\nhas('description', product)  // true\nhas('sub', product)  // true\nhas('b', product.sub)  // true\n\nconst hasSubB = prod =\u003e has('b', prod.sub)\nhasSubB(product)  // true\n```\n\n\n### hasIn\n\nReturns whether or not an object or its prototype chain has a property with\nthe specified name.\n\nNote that this method is similar as `has` with plain Objects, but he can\naccess to the prototype properties of the Function objects.\n\n```javascript\nfunction Rect (width, height) {\n  this.width = width\n  this.height = height\n}\n\nRect.prototype.area = function () {\n  return this.width * this.height\n}\n\nconst square = new Rect(2, 2)\nhasIn('width', square)  // true\nhasIn('area', square)  // true\nhasIn('name', square)  // false\n\n\nclass Circle {\n  constructor (r) {\n    this.rad = r\n  }\n\n  get diameter () { return this.rad * 2 }\n}\n\nconst circle = new Circle(20)\nhasIn('rad', circle)  // true\nhasIn('diameter', circle)  // true\nhasIn('name', circle)  // false\n```\n\n\n### isArray\n\nCheck if the parameter is an Array or not.\n\n```javascript\nisArray([])  // true\nisArray([1, 'yep', {a: 1, b: 2}])  // true\nisArray(true)  // false\nisArray(false)  // false\nisArray(NaN)  // false\nisArray({})  // false\n```\n\n\n### isEven\n\nCheck if a number is a multiple of 2.\n\n```javascript\nisEven(1)  // false\nisEven(2)  // true\nisEven(120)  // true\nisEven(113)  // false\n```\n\n\n### isFunction\n\nCheck if the parameter is a Function or not.\n\n```javascript\nisFunction(curry)  // true\nisFunction(() =\u003e {})  // true\nisFunction(function () { return true })  // true\nisFunction(true)  // false\nisFunction(false)  // false\nisFunction(NaN)  // false\nisFunction({})  // false\nisFunction([])  // false\nisFunction(123)  // false\n```\n\n\n### isInteger\n\nCheck if the parameter is an Integer or not.\n\n```javascript\nisInteger(1)  // true\nisInteger(123)  // true\nisInteger(1.23)  // false\nisInteger('')  // false\nisInteger('123')  // false\nisInteger(true)  // false\nisInteger(false)  // false\nisInteger(NaN)  // false\nisInteger([])  // false\nisInteger(() =\u003e {})  // false\n```\n\n\n### isNil\n\nChecks if `value` is `null` or `undefined`.\n\n```javascript\nisNil(null)  // true\nisNil(undefined)  // true\nisNil(NaN)  // false\nisNil(0)  // false\n```\n\n\n### isNumber\n\nCheck if the parameter is a Number or not.\n\n```javascript\nisNumber(1)  // true\nisNumber(123)  // true\nisNumber('123')  // false\nisNumber(true)  // false\nisNumber(false)  // false\nisNumber(NaN)  // true  NOTE: this is normal?!\nisNumber({})  // false\nisNumber([])  // false\nisNumber(() =\u003e {})  // false\n```\n\n\n### isObject\n\nCheck if the parameter is an Object or not.\n\n```javascript\nisObject({})  // true\nisObject(1)  // false\nisObject(123)  // false\nisObject('123')  // false\nisObject(true)  // false\nisObject(false)  // false\nisObject(NaN)  // false\nisObject([])  // false\nisObject(() =\u003e {})  // false\n```\n\n\n### isString\n\nCheck if the parameter is a String or not.\n\n```javascript\nisString('')  // true\nisString('hello')  // true\nisString('123')  // true\nisString(1)  // false\nisString(123)  // false\nisString(true)  // false\nisString(false)  // false\nisString(NaN)  // false\nisString([])  // false\nisString(() =\u003e {})  // false\n```\n\n\n### mapObject\n\nReturns the results of applying the `fn` to each element of the `object`.\nIn contrast to `Array.map` it returns an `object`.\n\n```javascript\nconst prependKeyAndDouble = (num, key, obj) =\u003e key + (num * 2)\nconst values = { x: 1, y: 2, z: 3 }\nmapObject(prependKeyAndDouble, values)  // { x: 'x2', y: 'y4', z: 'z6' }\n```\n\n\n### match\n\nTests a regular expression against a String.\nNote this method is similar to `R.match` https://github.com/ramda/ramda/blob/master/src/match.js\n\n```javascript\nmatch(/([a-z]a)/g, 'bananas') // ['ba', 'na', 'na']\nmatch(/a/, 'b') // []\nmatch(/a/, null) //=\u003e TypeError: null does not have a method named \"match\"\n```\n\n\n### max\n\nReturns the larger argument.\n\n```javascript\nmax(8765, 1224) // 8765\nmax('a', 'b'); // 'b'\n```\n\n\n### mean\n\nReturns the mean of the given list of numbers.\n\n```javascript\nmean([2, 7, 9]) // 6\nmean([]) // NaN\n```\n\n\n### median\n\nReturns the median of the given list of numbers.\n\n```javascript\nmedian([2, 9, 7])  // 7\nmedian([7, 2, 10, 9])  // 8\nmedian([1, 1, 2, 2])  // 1.5\nmedian([])  // NaN\n```\n\n\n### memoize\n\nSimple memoize function that takes in a function and returns a memoized function.\n\n```javascript\nconst factorial = memoize((x) =\u003e {\n  if (x === 0) {\n    return 1\n  } else {\n    return x * factorial(x - 1)\n  }\n})\n\nfactorial(5)  // calculate 5, 4, 3, 2, 1, 0 =\u003e 120\nfactorial(6)  // calculate 6 and fetch from cache 5 =\u003e 720\n```\n\n\n### merge\n\nCreate a new object with the properties of the first object merged with\nthe properties of the second object.\n\nNote If a key exists in both objects, the value from the second object will\nbe used.\n\n```javascript\nmerge({ 'name': 'fred', 'age': 32 }, { 'employment': developer })\n// { \"age\": 32, \"employment\": \"developer\", \"name\": \"fred\" }\n\nmerge({ 'name': 'sue', 'age': 31 }, { 'employment': 'developer', 'age': 28 })\n// { \"age\": 28, \"employment\": \"developer\", \"name\": \"sue\" }\n\nconst resetX = o =\u003e merge(o, {x: 0})\nresetX({x: 5, y: 2})  // { \"x\": 0, \"y\": 2 }\n```\n\n\n### min\n\nReturns the smaller argument.\n\n```javascript\nmin(8765, 1224) // 1224\nmin('a', 'b'); // 'a'\n```\n\n\n### modulo\n\nDivides the first parameter by the second and returns the remainder.\n\n```javascript\nmodulo(17, 3) // 2\nmodulo(-17, 3); // -2 JavaScript behavior\nmodulo(17, -3); // 2\n```\n\n\n### multiply\n\nMultiplies two numbers. Equivalent to `a * b`.\n\n```javascript\nmultiply(2, 5)  // 10\n\nconst double = n =\u003e multiply(n, 2)\nconst triple = n =\u003e multiply(n, 3)\ndouble(3)  // 6\ntriple(3)  // 9\n```\n\n\n### negate\n\nCreates a function that negates the result of the predicate `func`.\n\n```javascript\nconst list = [1, 2, 3, 4, 5, 6]\nlist.filter(negate(isEven))  // [1, 3, 5]\n```\n\n\n### none\n\nReturns `true` if no elements of the list match the predicate, `false` otherwise.\n\n```javascript\nconst list = [0, 1, 2, 3]\nconst list2 = [11, 12, 13, 14]\nconst bigger10 = n =\u003e n \u003e 10\n\nnone(bigger10, list)  // true\nnone(bigger10, list2)  // false\n```\n\n\n### not\n\nReturns the `!` of its argument. It will return `true` when passed falsy\nvalue and `false` when passed a truly one.\n\n```javascript\nnot(true)  // false\nnot(false)  // true\nnot(0)  // true\nnot(1)  // false\n```\n\n\n### nth\n\nReturns the nth element of the given list or String. If `n` is negative the\nelement at `list[length - negate(i)]` is returned.\n\n```javascript\nconst list = ['foo', 'bar', 'baz', 'fooz']\nnth(1, list)  // \"bar\"\nnth(-1, list)  // \"fooz\"\nnth(-99, list)  // `undefined`\nnth(2, 'abc')  // \"c\"\nnth(3, 'abc')  // \"\"\n```\n\n\n### omit\n\nReturns a new object omitting the keys specified.\n\n```javascript\nconst product = {\n  \"id\": 66443,\n  \"image\": \"aceb.png\",\n  \"width\": 965,\n  \"height\": 1040,\n  \"description\": \"Description goes here!\",\n  \"categories\": [\"4114\", \"4232\"],\n  \"brand\": \"Brand goes here!\",\n  \"price\": 9.99,\n  \"allergens\": {\n    \"a\": 'Allergen A',\n    \"b\": 'Allergen B'\n  }\n}\n\nomit(['id', 'price', 'brand'], product)\n// {\n//   \"allergens\": Object {\n//     \"a\": \"Allergen A\",\n//     \"b\": \"Allergen B\"\n//   },\n//   \"categories\": [\"4114\", \"4232\"],\n//   \"description\": \"Description goes here!\",\n//   \"height\": 1040,\n//   \"image\": \"aceb.png\",\n//   \"width\": 965\n// }\n```\n\n\n### or\n\nReturns `true` if one or both of its arguments are `true`. Returns `false`\nif both arguments are `false`.\n\n```javascript\nor(true, true)  // true\nor(true, false)  // true\nor(false, false)  // true\nor(false, false)  // false\n```\n\n\n### pairs\n\nConvert an object into a list of `[key, value]` pairs.\n\n```javascript\nconst values = { x: 1, y: 2, z: 3 }\npairs(values)  // [[\"x\", 1], [\"y\", 2], [\"z\", 3]\n```\n\n\n### path\n\nRetrieve the value at a given path.\n\n```javascript\nconst product = {\n  \"id\": 66443,\n  \"image\": \"aceb.png\",\n  \"width\": 965,\n  \"height\": 1040,\n  \"description\": \"Description goes here!\",\n  \"categories\": [\"4114\",\"4232\"],\n  \"brand\": \"Brand goes here!\",\n  \"price\": 9.99,\n  \"sub\": {\n    \"a\": 1000,\n    \"b\": 2000,\n    \"under\": {\n      \"a\": 10000000,\n      \"b\": 20000000,\n      \"superunder\": {\n        \"a\": 100000000000000,\n        \"b\": 200000000000000\n      }\n    }\n  }\n}\n\npath(['a', 'b'], { a: { b: 2 } })  // 2\npath(['sub', 'under', 'superunder', 'b'], product)  // 200000000000000\n```\n\n\n### percent\n\nCalculate the percentage `%` of a value. The firs parameter is the value and the\nsecond parameter is the percentage to calculate.\n\n```javascript\npercent(100, 50)  // 50\npercent(30, 20)  // 6\npercent(9.99, 10) // 0.9990000000000001\n\nconst percent50 = value =\u003e percent(value, 50)\npercent50(100)  // 50\n```\n\n\n### pick\n\nReads an array with multiple properties from an object and returns a partial\ncopy of an object with just those properties specified. If the key does not\nexist, the property is ignored.\n\n```javascript\npick(['a', 'd'], { a: 1, b: 2, c: 3, d: 4 })  // { a: 1, d: 4 }\npick(['a', 'e', 'f'], { a: 1, b: 2, c: 3, d: 4 })  // { a: 1 }\npick(['user'], { user: 'Bob', id: 2, age: 36 })  // { user: \"Bob\" }\n```\n\n\n### pipe\n\nPerforms `left-to-right` function composition. Takes a list of one or more\nfunctions and returns a new function.\n\nThe new function takes the same number of arguments as the first function\nit is given. It then, pipes those arguments through each function in the\nlist. It applies the first function to the arguments, passes its result to\nthe second function and so on.\n\nThe result of the last function is the result of the pipe call.\n\nNote that this is exactly the same as [compose](#compose) but with the functions in\nopposite order.\n\n```javascript\nconst inc = n =\u003e n + 1\nconst dbl = n =\u003e n * 2\nconst sqr = n =\u003e n * n\nconst operate = pipe(inc, dbl, sqr)\noperate(2)  // 36\noperate(5)  // 144\noperate(1)  // 16\n\n// NOTE: same example but with `compose` produces different value.\nconst operateCompose = compose(inc, dbl, sqr)\noperateCompose(1)  // 3\n```\n\n\n### pluck\n\nReturns a new list by plucking the same named property off all objects in\nthe list supplied.\n\n```javascript\npluck('a', [{a: 1}, {a: 2}])  // [1, 2]\npluck(0, [[1, 2], [3, 4]])  // [1, 3]\npluck('val', {a: {val: 3}, b: {val: 5}})  // [3, 5]\n```\n\n\n### prop\n\nReturns the value of the property to check for or `undefined`.\n\n**NOTE**: With a `Function` and ES6 `Class` objects the behavior is similar.\n\n```javascript\nconst product = {\n  \"id\": 66443,\n  \"image\": \"aceb.png\",\n  \"width\": 965,\n  \"height\": 1040,\n  \"description\": \"Description goes here!\",\n  \"categories\": [\"4114\",\"4232\"],\n  \"brand\": \"Brand goes here!\",\n  \"price\": 9.99,\n  \"sub\": {\n    \"a\": 1000,\n    \"b\": 2000\n  }\n}\n\nprop('price', product)  // 9.99\nprop('description', product)  // \"Description goes here!\"\netProp('sub', product)  // Object { \"a\": 1000, \"b\": 2000 }\nprop('b', prop('sub', product))  // 2000\n\nconst getPrice = prod =\u003e prop('price', prod)\ngetPrice(product)  // 9.99\n\nconst getSubB = prod =\u003e prop('b', prod.sub)\ngetSubB(product)  // 2000\n```\n\n\n### propOr\n\nIf the given object has an own property with the specified name, returns the\nvalue of that property. Otherwise returns the provided default value.\n\n```javascript\npropOr('The default property value.', 'unit_price', product)  // \"The default property value.\"\npropOr('The default property value.', 'price', product)  // 9.99\n```\n\n\n### randomBetween\n\nReturns a random number in a specified range (min and max inclusive).\n\n```javascript\nrandomBetween(100, 0)  // 54\nrandomBetween(100, 0)  // 81\nrandomBetween(100, 0)  // 29\nrandomBetween(-20, 100)  // 59\nrandomBetween(-100, 100)  // -18\n```\n\n\n### reject\n\nThe opposite of `filter` this method returns the elements of `list` that `fn`\ndoes **not** return truthy for.\n\n```javascript\nconst obj = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }\nconst arr = [1, 2, 3, 4]\nreject(obj, isEven)  // [1, 3]\nreject(arr, isEven)  // [1, 3]\n\nconst users = [\n  { 'user': 'barney', 'active': true },\n  { 'user': 'fred',   'active': false }\n]\nreject(users, ({ active }) =\u003e active)  // [{ 'user': 'fred',   'active': false }]\n```\n\n\n### remove\n\nRemoves the sub-list of `list` starting at index `start` and containing\n`count` elements.\n\nNote that this is a **copy** of the list. It does not modify the original.\n\n```javascript\nconst list = [1, 2, 3, 4, 5, 6, 7, 8]\nremove(2, 5, list)  // [1, 2, 8]\nremove(1, 1, list)  // [1, 3, 4, 5, 6, 7, 8]\n```\n\n\n### repeat\n\nReturns a fixed list of size `n` containing a specified identical value.\n\n```javascript\nconst obj = {}\nconst repObjs = n =\u003e repeat(obj, n)\nrepObjs(3)  // [{}, {}, {}]\nrepeat('str', 6)  // ['str', 'str', 'str', 'str', 'str', 'str']\n```\n\n\n### replace\n\nReplace a substring or regex match in a string with a replacement.\n\n```javascript\nreplace('foo', 'bar', 'foo foo foo')  // \"bar foo foo\"\nreplace(/foo/, 'bar', 'foo foo foo')  // \"bar foo foo\"\nreplace(/foo/g, 'bar', 'foo foo foo')  // \"bar bar bar\"\n```\n\n\n### reverse\n\nReturns a new list or string with the elements or characters in reverse\norder.\n\n```javascript\nreverse([1, 2, 3, 4])  // [4, 3, 2, 1]\nreverse('abcde')  // \"edcba\"\n```\n\n\n### sort\n\nReturns a copy of the list, sorted according to the comparator function.\n\nNote that this is a **copy** of the list. It does not modify the original.\n\n```javascript\nconst min = (a, b) =\u003e a \u003e b\nconst max = (a, b) =\u003e a \u003c b\nsort(min, [4, 2, 7, 5,])\nsort(min, [100, 1024, 768, 960])\nsort(min, [3.1, 1.4, 1, 1.7])\nsort(max, [4, 2, 7, 5])\nsort(max, [100, 1024, 768, 960])\n```\n\n\n### square\n\nMultiply a number `n` by itself.\n\n```javascript\nsquare(2)  // 4\nsquare(8)  // 64\nsquare(16)  // 256\n```\n\n\n### subtract\n\nSubtracts its second argument from its first argument.\n\n```javascript\nsubtract(10, 5)  // 5\nsubtract(10, 5, 1)  // 4\nsubtract('10', 5)  // 5\nsubtract(2, '3', 4)  // -5\nsubtract('5', '5')  // 10\nsubtract('aa', 3)  // NaN\n\n// NOTE: I need think on implemet placeholder Symbol or like to solve this.\nconst subtract2 = curry(subtract, 2)\nsubtract2(100)  // -98\n-subtract2(100)  // 98\n\nconst subtract2 = x =\u003e subtract(2, x)\n```\n\n\n### sum\n\nAdds together all the elements of a list.\n\n```javascript\nsum([1])  // 1\nsum([1, 1])  // 2\nsum([1, 2, 4])  // 7\nsum(['1', 2, 4])  // 7\nsum(['1', '2', '4'])  // 7\n\nconst sum10 = list =\u003e sum([...list, 10])\nsum10([1, 2, 4])  // 17\n```\n\n\n### take\n\nReturns a new array with the first `n` elements of the given `list` or string.\n\n```javascript\nconst arr = ['foo', 'bar', 'baz']\ntake(1, arr)  // [\"foo\"]\ntake(2, arr)  // [\"foo\", \"bar\"]\ntake(3, arr)  // ['foo', 'bar', 'baz']\ntake(4, arr)  // ['foo', 'bar', 'baz']\n```\n\n\n### throttle\n\nAdds together all the elements of a list.\n\n```javascript\nwindow.addEventListener('resize', throttle(() =\u003e console.log('resizing') , 2000, { inmediate: true }))\n```\n\n\n### times\n\nReturns an Array containing the results of call an input function `n` times.\nNote that `fn` is passed one argument: the current value of `n`.\n\n```javascript\nconst family = [\n  { 'name': 'pilar', 'age': 20 },\n  { 'name': 'alberto', 'age': 3 },\n  { 'name': 'edgar', 'age': 30 }\n  ]\n\nconst foo = n =\u003e family[n].name\nconst baz = n =\u003e n\ntimes(foo, family.length)  // ['pilar', 'alberto', 'edgar']\ntimes(baz, 100))  // [0, 1, 2, ..., 99]\n```\n\n\n### truncate\n\nTruncate a long strings to max num of characters and add ellipsis to the end.\n\n```javascript\ntruncate('Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 12)  // \"Lorem ipsum...\"\ntruncate('Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 12, ' 🙌🏻')  // \"Lorem ipsum 🙌🏻\"\n```\n\n\n### uniq\n\nReturns a new list containing only one copy of each element in the original list.\n\n```javascript\nuniq([1, 2, 1, 4, 1, 3])  // [1, 2, 4, 3]\nuniq(['a', 'b', 'c', 'a', 'd'])  // [\"a\", \"b\", \"c\", \"d\"]\n```\n\n\n### uniqBy\n\nReturns a new list containing one copy of each unique element in the original\nlist filtered by `prop` parameter.\n\nNote that if the supplied function produces the same value on two items, prefers\nthe first item.\n\n```javascript\nconst people = [\n   { 'id': 1, 'name': 'edgar' },\n   { 'id': 1, 'name': 'pilar' },\n   { 'id': 1, 'name': 'pilar' },\n   { 'id': 2, 'name': 'ivan' },\n   { 'id': 2, 'name': 'inma' }\n ]\n*\n uniqBy('id', people)  // [{ 'id': 1, 'name': 'edgar' }, { 'id': 2, 'name': 'ivan'}]\n uniqBy('name', people)  // [{ 'id': 1, 'name': 'edgar' }, { 'id': 1, 'name': 'pilar' }, { 'id': 2, 'name': 'ivan'}, { 'id': 2, 'name': 'inma'}]\n uniqBy((o) =\u003e o.id, people)  // [{ 'id': 1, 'name': 'edgar' }, { 'id': 2, 'name': 'ivan'}]\n```\n\n\n### update\n\nReturns a copy of the array with the element at the provided index\nreplaced with the given value.\n\nNote that is the result to apply `always` method with the new value\nas argument of the first parameter for the `adjust` method.\n\nSee [adjust](#adjust) and [always](#always)\n\n```javascript\nupdate(1, 'new', [1, 2, 3])  // [1, \"new\", 3]\n```\n\n\n### when\n\nTests the final argument by passing it to the given predicate function.\nIf the predicate is true, the function will return the result of calling\nthe `when` function with the same argument. If the predicate is false,\nthe argument is returned.\n\n```javascript\nconst truncate10 = str =\u003e truncate(str, 10)\nconst isLarge = n =\u003e n.length \u003e 10\nconst truncateIf = text =\u003e when(isLarge, truncate10, text)\ntruncateIf('0123456789Aeasd')  // \"0123456789...\"\n```\n\n---\n\n## TODO\n\n- Add tests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedgarberm%2Fpills","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedgarberm%2Fpills","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedgarberm%2Fpills/lists"}