Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

pico sized functional library

License

NotificationsYou must be signed in to change notification settings

trainyard/pico-lambda

Repository files navigation

λ
Arrays, Strings and things the functional way
A640b functional library based on native methods
Build StatusDownloadssemistandard
Proudly supported by...
BrowserStack

Rationale

We needed to optimize the bundle size of our projects. Since we were already using ES6 and transpiling it, we decided to create a functional library that takes the native Array and String APIs used by major browsers and Nodejs, and make themfunctional - so we cancurry,compose, andpipe them. If you are either already transpiling es6 in your project, or you are not supporting older browsers, you should use this instead oframda orlodash/fp. If you need to support older browsers, are not transpiling es6, or using es5 - you should uselodash/fp orramda

Features

  • Pico: weighs less than 700 bytes when minified and gzipped.
  • Useful: takes most native JavaScript array and string methods and makes themimmutable,curried, andcomposable.
  • Functional: Curry, compose and pipe, Oh My!
  • Familiar: same names just curried and composable. SeeJavaScript Array andJavaScript String.
  • Degrades Gracefully: a small set of these functions are not available in every browser/environment. When not available in the browser it will not be available in Pico Lambda.

Pico-lambda was made for the ES6 Javascript Runtime. It hasno dependencies.


Example

After installing vianpm install:

const{parray, pcore}=require('pico-lambda')const{  concat,  filter,  map,  reduce,}=parrayconst{  compose}=pcore//concatconstarrayOne=[1,2,3];constaddTwo=concat([4,5])constresult=addTwo(arrayOne)// We can compose instead of chainingcompose(reduce((acc,val)=>val+acc,0),map(x=>x*2),filter(x=>x>5),concat([6,7,8]))([1,2,3,4,5])

functions

This table shows compatibility for each of the functions available by browser.Currently only array functions are listed. String will be added soon.If you wish to have full compatibility you can use a transpiler like babel.

Table of Compatibility
Function Android 5.1+ Chrome 52+ Edge 13+ FF 45+ iOS 9+ Safari 9+
compose
concat
copyWithin
entries
every
fill
filter
find
findIndex
includes
indexOf
join
keys
lastIndexOf
map
pipe
pop
push
reduce
reduceRight
reverse
shift
slice
splice
some
sort
toLocaleString
toString
unshift

API

The api is broken up into three sections:

  • pcore - Basic functional capabilities like curry and compose
  • parray - The standard Array.prototype methods setup for functional use
  • pstring - The standard String.prototype methods setup for functional use

One note, parray and pstring have some overlapping function names:

  • length
  • toString
  • slice
  • indexOf
  • lastIndexOf
  • includes
  • concat

Be aware of this when importing these into your global namespace.


pcore


pipe ::((a -> b), (b -> c), ..., (e -> f)) -> a -> f

Takes an initial value that is passed to the first function in the parameter list.The return value of each subsequent function is passed to the following function.The return value of the last function is returned from pipe.

constarr=[1,2,3,4,5]pipe(unshift(0),// (a -> b)concat([6,7,8])// (b -> c))(arr)// => [0, 1, 2, 3, 4, 5, 6, 7, 8]

compose ::((e -> f), ..., (b -> c), (a -> b)) -> a -> f

Evaluates the provided functions, right to left, passing the return valueof each function to the next in line.The initial function is passed the initial value provided to compose.The output of the final function, in the above case(e->f), is returned.

compose(map(x=>x+1),// (c -> d)map(x=>x+1),// (b -> c)map(x=>x+1)// (a -> b))([0])// (-> a) => 3

curry ::(fn) -> fn

Takes a function and curries the arguments.

Take note that rest parameters are only partially supported using curry. JS only reports expected parameters, optional and rest parameters are not reported. As a result, there is no way to determine when to expect them. What this means, in practice, is that you can pass rest and/or optional parameters along with the last required param, but you cannot pass them on their own in a new set of parens. See the example below for an illustration of this.

functionlog4Things(a,b,c,d){console.log(a,b,c,d)}constcurriedLog=curry(log4Things)curriedLog(1,2,3,4)//=> Outputs: 1 2 3 4curriedLog(1)(2)(3)(4)//=> Outputs: 1 2 3 4curriedLog(1)(2,3)(4)//=> Outputs: 1 2 3 4curriedLog(1)(2)(3)(4)//=> Outputs: 1 2 3 4curriedLog(1,2)(3,4)//=> Outputs: 1 2 3 4curriedLog(1,2,3)(4)//=> Outputs: 1 2 3 4//You get the idea.....constpartialLog=curriedLog(1,2,3)partialLog(4)//=> Outputs: 1 2 3 4partialLog(5)//=> Outputs: 1 2 3 5//Using Rest parametersfunctionlog3OrMoreThings(a,b,c, ...d){console.log(a,b,c, ...d)}constcurriedLogMore=curry(log3OrMoreThings)curriedLogMore(1,2,3)//=> Outputs: 1 2 3curriedLogMore(1,2,3,4)//=> Outputs: 1 2 3 4curriedLogMore(1,2)(3)//=> Outputs: 1 2 3curriedLogMore(1,2)(3,4)//=> Outputs: 1 2 3 4//However, the following all result in an errorcurriedLogMore(1)(2)(3)(4)//Throws: TypeError('curriedLogMore(...)(...)(...) is not a function')curriedLogMore(1)(2,3)(4)//Throws: TypeError('curriedLogMore(...)(...)(...) is not a function')curriedLogMore(1)(2)(3)(4)//Throws: TypeError('curriedLogMore(...)(...)(...) is not a function')curriedLogMore(1,2,3)(4)//Throws: TypeError('curriedLogMore(...)(...)(...) is not a function')//This is because the curry function calls the original function after the third param and the result is then called as a function with the last grouping, '(4)' in this case

identity ::a -> a

Takes an argument and returns that arugment. This can be quite useful when composing many functions together.

console.log(identity("hi"))//Outputs: hi

parray


concat ::[a] -> ([a], ..., [a]) -> [a]

Concatenates two or more arrays

concat([4,5])([1,2,3])// => [1, 2, 3, 4, 5]concat([4,5])([1,2],[3])// => [1, 2, 3, 4, 5]

SeeArray.concat (MDN)

copyWithin ::(Int, Int, Int) -> [a] -> [a] |(Int, Int) -> [a] -> [a]

Makes a shallow copy of part of an array and overwrites another location in the same with the copy. Size is kept constant.

  • The first Int is the target index to write the copy to.
  • The second Int is the index to start the copy from.
  • The third, optional, Int specifies the end of the range to copy (exclusive of the end index). If not provided, it goes to the end of the array.
constarr=[1,2,3,4,5]copyWithin(3,1)(arr)// => [1, 2, 3, 2, 3]copyWithin(3,1,2)(arr)// => [1, 2, 3, 2, 5]

SeeArray.copyWithin (MDN)

entries::[a] -> [b]

Return an iterator over key, value pairs from the array.

constiterator=entries([1,2,3,4,5])iterator.next()// => { value: [0, 1], done: false }

SeeArray.entries (MDN)

every ::((a, Int, [a]) -> Boolean) -> [a] -> Boolean

Applies predicate to all elements in array and returns false if any fail. The predicate function must at least take one parameter for each element but may optionally take an index and the entire array as 2nd and 3rd parameters, respectively.

constpredicate=x=>x<4every(predicate)([1,2,3])// => trueevery(predicate)([1,2,3,4,5])// => false

SeeArray.every (MDN)

fill ::(a, Int, Int) -> [a] -> [a] |(a) -> [a] -> [a]

Fills a portion of the given array putting the same new value into each slot.

  • The first parameters (a) is the element to add into the array
  • The second parameter (Int) is the first index to start filling at. If not supplied it starts at 0.
  • The third parameter (Int) is the index to stop filling before (i.e., exclusive). If not supplied fill goes to the end of the array.
constarr=[1,2,3,4,5]fill(1)(arr)// => [1, 1, 1, 1, 1]fill(1,2,4)(arr)// => [1, 2, 1, 1, 5]

SeeArray.fill (MDN)

filter ::((a, Int, [a]) -> Boolean) -> [a] -> [a]

Returns a new array containing only those elements of the given array that pass the given predicate.

constpredicate=x=>x<3filter(predicate)([1,2,3,4,5])// => [1, 2]

SeeArray.filter (MDN)

find ::(a -> Boolean) -> [a] -> a | undefined

Finds and returns the first element in the given array that matches the given predicate. If no element passes, undefined is returned.

constpredicate=x=>x===3find(predicate)([1,2,3])// => 3find(predicate)([1,2])// => undefined

SeeArray.find (MDN)

findIndex ::(a -> Boolean) -> [a] -> Int

Returns the index of the first element in the given array that matches the given predicate. If no element passes, -1 is returned.

constarr=[1,2,3,4,5]constfindIndex=x=>x===3find(x=>x>3)(arr)// => 3find(x=>x>80)(arr])// => -1

SeeArray.findIndex (MDN)

includes ::a -> [a] -> Boolean

Returns true if the given element is in the given array, otherwise false.

constanimals=['dog','cat','ferret','hamster']consthasCat=includes('cat')consthasUnicorn=includes('unicorn')hasCat(animals)// truehasUnicorn(animals)// false

SeeArray.includes (MDN)

indexOf ::(a, Int) -> [a] -> Int |(a) -> [a] -> Int

Returns the index of the given element if it is in the given array, otherwise -1.The 2nd parameter can be used to change where it starts looking.

indexOf(3)([1,2,3,4,5])// => 2indexOf(3,3)([[1,2,3,4,5,3])// => 3

SeeArray.indexOf (MDN)

join ::String -> [a] -> String

Converts each element of the array to a string and concatenates them together with the given string as a delimiter.

join('-')([1,2,3])// => '1-2-3'

SeeArray.join (MDN)

keys ::[a] -> [Int]

Return an iterator over keys from the array.

constiterator=keys([1,2,3,4,5])iterator.next()// => { value: 0, done: false }

SeeArray.keys (MDN)

lastIndexOf ::(a, Int) -> [a] -> Int |(a) -> [a] -> Int

Works like indexOf but starts at the end and works backwards.The 2nd parameter can be used to tell it where to start working backwards from.

lastIndexOf(1)([1,2,3,1])// => 3lastIndexOf(1,-2)([1,2,3,1])// => 0

SeeArray.lastIndexOf (MDN)

map ::(a -> b) -> [a] -> [b]

Applies a function over each element in the given array, returning a new array with each function call's results.

map(x=>x*2)([1,2,3])// => 2, 4, 6

SeeArray.map (MDN)

pop ::[a] -> [a]

Returns a new array without the last item

pop([1,2,3,4,5])// => [1, 2, 3, 4]

SeeArray.pop (MDN)

push ::a -> [a] -> [a]

Returns a new array with the new element appended to the end of the original array.

push(5)([1,2,3,4])// => [1, 2, 3, 4, 5]

SeeArray.push (MDN)

reduce ::((a, b) -> a) -> a -> [b] -> a

Applies a function against an accumulator and each value of the array (from left-to-right), then returning the accumulator.

constsum=reduce((acc,val)=>acc+val,99)sum([2,3,4])// => 108

SeeArray.reduce (MDN)

reduceRight ::((a, b) -> a) -> a -> [b] -> a

Applies a function against an accumulator and each value of the array (from right-to-left), then returning the accumulator.

constsum=reduceRight((acc,val)=>acc+val,99)sum([2,3,4])// => 90

SeeArray.reduceRight (MDN)

reverse ::[a] -> [a]

Returns a new array with the elements in reverse order.

reverse([1,2,3,4,5])// => [5, 4, 3, 2, 1]

SeeArray.reverse (MDN)

shift ::[a] -> [a]

Returns a new array with the first element removed.

shift([1,2,3,4,5])// => [2, 3, 4, 5]

SeeArray.shift (MDN)

slice ::(int, int) -> [a] -> [a]

Takes a slice from a given array and returns it as a new array.

constremoveFirst=slice(1)removeFirst([2,3,4])// => [3, 4]

SeeArray.slice (MDN)

splice ::(int, int, [a]) -> [a] -> [a]

Returns a new array with the indicated elements removed. An optional set of new elements can be inserted in their place.

consttakeTwo=splice(2)takeTwo([1,2,3,4,5])// => [1, 2]

SeeArray.splice (MDN)

some ::(a -> Boolean) -> [a] -> Boolean

Returns true if any element in the given array matches the given predicate.

constlessThanFour=some(x=>x<4)lessThanFour([1,2,3,4,5])// => true

SeeArray.some (MDN)

sort ::((a, a) -> int) -> [a] -> [a]

Returns a copy of the original array with the values sorted. If a comparator function is provided it should return -1, 0 or 1 depending on whether the first element is less than, equal to or greater than the second, respectively. If no comparator is given, lexical sorting is used.

constnumComp=(a,b)=>(a<b) ?-1 :(a===b) ?0 :1constsortBy=sort(numComp)sortBy([20,1,3,4,2])// => [1, 2, 3, 4, 20]

SeeArray.sort (MDN)

toLocaleString ::(String, Obj) -> [a] -> String

Converts each element of an array into a string based on current locale settings or locale options passed in. The resulting strings are appended together using commas.

consttoYen=toLocaleString('ja-JP',{style:'currency',currency:'JPY'})toYen(["¥7",500,8123,12])// => ¥7,500,8,123,12

SeeArray.toLocaleString (MDN)

toString ::[a] -> String

Converts each element of an array into a string and appends them together with a comma.

toString([1,2,3,4,5])// => '1,2,3,4,5'

SeeArray.toString (MDN)

unshift ::a -> [a] -> [a]

Returns a new copy of an array with the given element added to the front.

constaddOne=unshift(1)addOne([2,3])// => [1, 2, 3]

SeeArray.unshift (MDN)

Where are ...?

  • length - This is a property, not a method, so it doesn't really belong here.
  • forEach - This is inherently side-effect-y, it adds nothing that can't be done withfilter,map andreduce.

If you don't agree with anything above that's great! Just log an issue so we can discuss.


pstring


charAt ::Int -> String -> String

Returns the character at the given position in the string.

charAt(2)("123"))//=> "3"

SeeString.charAt (MDN)

charCodeAt ::Int -> String -> Int

Returns the character code at the given position in the string.

charAt(2)("123"))//=> 51

SeeString.charCodeAt (MDN)

codePointAt ::Int -> String -> Int

Returns the unicode code point at the given index.

codePointAt(0)("\uD800\uDC00"))//=> 65536

SeeString.codePointAt (MDN)

concat ::(String, ...String) -> String -> String

Returns a new string combining the given strings. Multiple strings can be passed to the initial call.

conststringOne="123"constaddTwo=concat("45","67")constresult=addTwo(stringOne)//result = "1234567"

SeeString.concat (MDN)

endsWith ::String -> String -> Boolean |(String, Int) -> String -> String

Returns true if the second string ends with the characters in the first. If the integer parameter is passed, the second string is considered to be only that long (or the length of the second string itself whichever is shorter)

endsWith("bc")("abc")//=> trueendsWith("bc",2)("abc")//=> falseendsWith("bc")("abcd")//=> false

SeeString.endsWidth (MDN)

includes ::String -> String -> Boolean |(String, Int) -> String -> Boolean

Returns true if the characters from the first string appear together as a substring in the second. If the integer is provided it indicates where to start searching in the second string.

includes("not to be,")("To be, or not to be, that is the question.")//=> trueincludes("not to be,",20)("To be, or not to be, that is the question.")//=> falseincludes("nonexistent")("To be, or not to be, that is the question.")//=> false

SeeString.includes (MDN)

indexOf ::String -> String -> Int |(String, Int) -> String -> Int

Returns the first index where the second string appears as a substring of the first. Optionally you can provide a starting index and the search will start there. If the first string is not found it returns -1

indexOf("a")("abc")//=> 0indexOf("b")("abc")//=> 1indexOf("c")("abc")//=> 2indexOf("z")("abc")//=> -1

SeeString.indexOf (MDN)

lastIndexOf ::String -> String -> Int |(String, Int) -> String -> Int

Works like index of but starting at the end and working forward.

lastIndexOf("a")("abc")//=> 0lastIndexOf("b")("abc")//=> 1lastIndexOf("c")("abc")//=> 2lastIndexOf("z")("abc")//=> -1

SeeString.lastIndexOf (MDN)

localeCompare ::String -> String -> Int |(String, String) -> String -> Int |(String, String, Object) -> String -> Int

Compares two strings taking the locale into account. The return value will be negative if the second string comes before the first. Positive if it comes later. And zero if they are equal. The additional, optional parameters allow a locale and other options to be specified.

localeCompare("b")("a")//=> <0localeCompare("a")("b")//=> >0localeCompare("a")("a")//=> 0localeCompare('a','de',{sensitivity:'base'})('ä')//=> 0

SeeString.localeCompare (MDN)

match ::Regexp -> String -> [String]

Returns an array of strings for the value matched by the regular expression as well as all matching groups defined therein.

conststr='For more information, see Chapter 3.4.5.1'constre=/see(chapter\d+(\.\d)*)/imatch(re)(str)//=> ["see Chapter 3.4.5.1", "Chapter 3.4.5.1", ".1"]

SeeString.match (MDN)

normalize ::String -> String

Returns the Unicode Normalization Form of a string.

normalize('NFKC')('\u1E9B\u0323')//=> '\u1E69'

SeeString.normalize (MDN)

repeat ::Int -> String -> String

Returns string comprised of the given number of repeats of the given string.

repeat(2)('abc')//=> 'abcabc'

SeeString.repeat (MDN)

replace ::(Regexp, String) -> String -> String

Replaces all locations in the second string that match the given regular expression with the value in the first string. Back references in the first string will be filled appropriately.

replace(/xmas/i,'Christmas')('Twas the night before Xmas...'))//=> 'Twas the night before Christmas...'

SeeString.replace (MDN)

search ::Regexp -> String -> String

Returns the first position where given regular expression matches in the second string. If it doesn't match, -1 is returned.

search(/xmas/i)('Twas the night before Xmas...'))//=> 22

SeeString.search (MDN)

slice ::Int -> String -> String |(Int, Int) -> String -> String

Returns a substring of the second string defined by the given index and optional end index. Either may be negative to count from the end of the string.

slice(4,-2)('Twas the night before Xmas...')//=> ' the night before Xmas.'

SeeString.slice (MDN)

split ::String -> String -> [String] |(String, Int) -> String -> [String]

Splits a string into an array of substrings that are separated by the first string given. If the integer parameter is provided the split will stop at the given limit.

split(',')("1,2")//=> ['1', '2']split(',',2)("1,2,3,4")//=> ['1', '2']

SeeString.split (MDN)

startsWith ::String -> String -> Boolean |(String, Int) -> String -> Boolean

Returns true if the second string starts with the characters in the first. If the integer parameter is passed, the second string is considered to start at that position

startsWith("ab")("abc")//=> truestartsWith("bc")("abcd")//=> false

SeeString.startsWith (MDN)

substr ::Int -> String |(Int, Int) -> String

Returns the characters in a string beginning at the specified location through the specified number of characters.

substr(2)("abcde")//=> 'cde'substr(2,2)("abcde")//=> 'cd'

SeeString.substr (MDN)

substring ::Int -> String |(Int, Int) -> String

Returns a subset of a string between one index and another, or through the end of the string.

substring(2)("abcde")//=> 'cde'substring(2,4)("abcde")//=> 'cd'

SeeString.substring (MDN)

toLocaleLowerCase ::String -> String

Returns the primitive value of a string.

SeeString.toLocaleLowerCase (MDN)

toLocaleUpperCase ::String -> String

Returns the calling string value converted to lower case, according to any locale-specific case mappings.

toLocaleLowerCase("ABC")//=> 'abc'

SeeString.toLocaleUpperCase (MDN)

toLowerCase ::String -> String

Returns the primitive value of a string.

toLocaleLowerCase("ABC")//=> 'abc'

SeeString.toLowerCase (MDN)

toString ::String -> String

Returns the calling string value converted to upper case, according to any locale-specific case mappings.

toLocaleUpperCase("abc")//=> 'ABC'

SeeString.toString (MDN)

toUpperCase ::String -> String

Returns the calling string value converted to upper case.

toUpperCase("abc")//=> 'ABC'

SeeString.toUpperCase (MDN)

trim ::String -> String

Removes whitespace from both ends of a string. Whitespace in this context is all the whitespace characters (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.).

trim(" abc ")//=> 'abc'

SeeString.trim (MDN)

trimLeft ::String -> String

Removes whitespace from the left end of a string. Whitespace in this context is all the whitespace characters (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.).

trimLeft(" abc ")//=> 'abc '

SeeString.trimLeft (MDN)

trimRight ::String -> String

Removes whitespace from the left end of a string. Whitespace in this context is all the whitespace characters (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.).

trimRight(" abc ")//=> ' abc'

SeeString.trimRight (MDN)

valueOf ::String -> String

Returns the primitive value of a string.

valueOf("abc")//=> 'abc'

SeeString.valueOf (MDN)

About

pico sized functional library

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors5


[8]ページ先頭

©2009-2025 Movatter.jp