diff --git a/files/docs/moses/CHANGELOG.md b/files/docs/moses/CHANGELOG.md new file mode 100644 index 0000000..11781e0 --- /dev/null +++ b/files/docs/moses/CHANGELOG.md @@ -0,0 +1,133 @@ +#Version history# + +##1.4.0 (07/14/14) + +###Breaking +#### Changes +* Aliases are available by default +* `_.find` is no longer an alias to `_.detect` +* Provided a new implementation of `_.unique`, removed argument `_.isSorted` +* `_.isNil` now returns true if arg is nil, an empty string or empty table and false otherwise. +* `_.size` now returns 0 for empty args instead of `nil` +* `_.unique` no longer accepts `iter` argument to transform original array values. +* `_.cycle` argument `n` now defaults to 1. +* `_.groupBy` no longer handles `iter` as a string + +#### Renamed +* Renamed alias `_.uId` to `_.uid` +* Renamed `_.add` to `_.addTop` +* Renamed `_.uniq` as alias to `_.unique` +* Renamed `_.symmetric_difference` to `_.symmetricDifference` + +#### Removed +* Removed `_.paired` + +###Improvements & bugfixes +* `_.reduce` now supports an array of booleans +* `_.pick` now picks false values +* `_.concat` args `i` and `j` defaults explicitely to 1 and array length (for compatibility with LuaJIT) +* `_.pop` now takes an optional extra-arg n, to be the number of values to be popped +* `_.unshift` now takes an optional extra-arg n, to be the number of values to be retrieved +* Moved explicitely `_.toArray` to array functions +* `_.functions` accepts an extra-arg to prevent from looking-up for methods in metatables. + +### New functions (and aliases) +* Added `_.find` +* Added `_.pipe` +* Added `_.complement` +* Added `_.juxtapose` and alias `_.juxt` +* Added `_.isunique` and alias `_.isuniq` +* Added `_.rep` +* Added `_.interleave` +* Added `_.interpose` +* Added `_.partition` and alias `_.part` +* Added `_.permutation` and alias `_.perm` +* Added `_.compare` as alias to `_.isEqual` +* Added `_.isIterable` +* Added `_.toBoolean` +* Added `_.pull` and alias `_.remove` +* Added `_.at` + +### New aliases +* Added `_.xor` as alias to `_.symmetricDifference` + +##1.3.2.1 (04/22/13) +Renamed global `MOSES_NO_ALIASES` to global `MOSES_ALIASES`. Aliases are not available by default. + +##1.3.2 (04/19/13) +Added `_.import`, export library to context or _G +Added `noConflict` option to `_.import` +Added `MOSES_NO_ALIASES` option when requiring the library +Added `_.symmetric_difference` +Added `_.eachi` +Added `_.isInteger` +Added `_.cycle` +Added `_.count` +Added `_.countf` +Added `_.chunk` (inspired from Ruby's Enumerable [#chunk](http://ruby-doc.org/core-2.0/Enumerable.html#method-i-chunk)) +Added `_.chop` as alias to `_.removeRange` +Added `_.skip` as alias to `_.last` +Added `_.diff` as alias to `_.difference` +Added `_.symdiff` as alias to `_.symmetric_difference` +Added `_.forEachi` as alias to `_.eachi` +Added `_.loop` as alias to `_.cycle` +Renamed `_.pairs` to `_.paired` +Removed `_.count` as alias to `_.range` +Changed `_.difference behaviour`, now takes up to two arrays as args +Fixed internal inconsistencies with aliases, should not be used internally with regards to `MOSES_NO_ALIASES` option. +Fixed `_.each` implementation, should not return anything + +##1.3.1 (04/12/13) +* Added chaining interface +* Renamed `_.isObject` to `_.isTable` +* Added `_.tap`, `_.chain`, `_()` and `_.value` +* Added `_.findWhere` +* Added `_.contains` +* _.functions no longer takes an output table +* Changed _.isArray behaviour, returns true only for real Lua arrays +* Updated specs +* Updated docs and samples + +##1.3.0 (11/12/12) +* Removed _.iterate (slower than pairs, ipairs) +* Added _.identity +* Removed _.curry (was more like a closure, will provide a proper implementation later) +* Removed _.iter_to_array +* Most of all functions rewritten +* _.import/_.mixin now imports library functions to the global env. +* Added type checking functions as object functions +* Added new functions and aliases : Moses has 85 unique functions, 117 counting aliases. +* Added HTML docs +* Added Specs +* Added samples + +##1.2.1 (08/20/12) +* Added `_.takeWhile` (as alias to `_.selectWhile`) +* Added `_.dropWhile` and `_.rejectWhile` (as alias) +* Updated Moses_Lib_Test.lua +* Updated documentation + +##1.2 (08/19/12) +* Added `_.selectWhile` +* Added `_.mapReduce` and `_.mapr` (as alias) +* Added `_.mapReduceRight` and `_.maprr` (as alias) +* Added `_.bindn` +* Added `_.appendLists` +* Updated Moses_Lib_Test.lua +* Updated documentation + +##1.1 (08/04/12) +* Removed `_.contains` as alias to `_.include` +* Added `_.removeRange` (as Array function) +* Added `_.sameKeys` and `_.contains` (as Collection functions) +* Added `_.bind` (as Utility function) +* Updated Moses_Lib_Test.lua +* Updated documentation + +##1.0 (08/02/12) +* Added `_.append`, `_.invert`, `_.import`, `_.template`, `_.curry` +* Updated Moses_Lib_Test.lua +* Updated documentation + +##0.1 (07/24/12) +* Initial Release diff --git a/files/docs/moses/LICENSE b/files/docs/moses/LICENSE new file mode 100644 index 0000000..f06dce3 --- /dev/null +++ b/files/docs/moses/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2012-2014 Roland Yonaba + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/files/docs/moses/README.md b/files/docs/moses/README.md new file mode 100644 index 0000000..e9f0350 --- /dev/null +++ b/files/docs/moses/README.md @@ -0,0 +1,69 @@ +[![Build Status](https://travis-ci.org/Yonaba/Moses.png)](https://travis-ci.org/Yonaba/Moses) +[![Coverage Status](https://coveralls.io/repos/Yonaba/Moses/badge.png?branch=master)](https://coveralls.io/r/Yonaba/Moses?branch=master) +[![License](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](LICENSE) + +A Lua utility-belt library for [functional programming](http://en.wikipedia.org/wiki/Functional_programming). It complements the built-in __Lua table library__, making easier +operations on arrays, lists, collections.
+ +__Moses__ was deeply inspired by [Underscore.js](http://documentcloud.github.com/underscore/). + +##Download & Installation +###Bash + +```bash +git clone git://github.com/Yonaba/Moses.git +```` + +###Archive +* __zip__: [latest stable 1.4.0](http://github.com/Yonaba/Moses/archive/Moses-1.4.0-1.zip) | [current](http://github.com/Yonaba/Moses/archive/master.zip) | [all](http://github.com/Yonaba/Moses/tags) +* __tarball__: [latest stable 1.4.0](http://github.com/Yonaba/Moses/archive/Moses-1.4.0-1.tar.gz) | [current](http://github.com/Yonaba/Moses/archive/master.tar.gz) | [all](http://github.com/Yonaba/Moses/tags) + +###LuaRocks +``` +luarocks install moses +```` + +###MoonRocks + +```bash +moonrocks install moses +```` + +or : + +```bash +luarocks install --server=http://rocks.moonscript.org/manifests/Yonaba moses +```` + +##Usage## +Put the file [moses.lua](https://github.com/Yonaba/Moses/blob/master/moses.lua) inside your project folder and call it using *require* command. + +*Note:* the full source [moses.lua](https://github.com/Yonaba/Moses/blob/master/moses.lua) is quite heavy (~59 kiB). You can alternatively use the [minified version](https://github.com/Yonaba/Moses/blob/master/moses_min.lua) (~17.5 kiB). + +##Tutorial## +Find a complete set of code examples in [tutorial.md](https://github.com/Yonaba/Moses/blob/master/doc/tutorial.md) + +##Documentation## +* Available in HTML-format for download : see [doc](https://github.com/Yonaba/Moses/blob/master/doc). +* Read it in your browser : see [online doc](http://yonaba.github.io/Moses/doc) + +##Credits and Acknowledgement## +* [Jeremy Ashkenas](https://github.com/jashkenas), for the amazing [Underscore.js](http://documentcloud.github.com/underscore/) +* [Marcus Irven](http://mirven.github.com/underscore.lua/)'s and [JTArchie](https://github.com/jtarchie/underscore-lua)'s 1-to-1 ports that also inspired this. +* [LDoc](https://github.com/stevedonovan/ldoc/) (from *Steve Donovan*) used to generate the current HTML documentation. + +##Specification +Spec tests have been included.
+Run them using [Telescope](https://github.com/norman/telescope) with the following command from the root folder: + +```bash +tsc -f spec/* +``` + +##License## +This work is under [MIT-LICENSE](http://www.opensource.org/licenses/mit-license.php)
+Copyright (c) 2012-2014 Roland Yonaba.
+See [LICENSE](LICENSE). + +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/Yonaba/moses/trend.png)](https://bitdeli.com/free "Bitdeli Badge") + diff --git a/files/docs/moses/index.html b/files/docs/moses/index.html new file mode 100644 index 0000000..cdea428 --- /dev/null +++ b/files/docs/moses/index.html @@ -0,0 +1,4146 @@ + + + + + Moses documentation + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Module moses

+ +

Utility-belt library for functional programming in Lua.
+ Source on Github

+

+ +

+

Info:

+
    +
  • License: MIT
  • +
  • Copyright: 2012-2014
  • +
  • Author: Roland Yonaba
  • +
  • Release: 1.4.0
  • +
+ + +

Table functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
each (t, f[, ...])Iterates on each key-value pairs in a table.
eachi (t, f[, ...])Iterates on each integer key-value pairs in a table.
at (t, ...)Returns an array of values at specific indexes and keys.
count (t[, value])Counts occurrences of a given value in a table.
countf (t, f[, ...])Counts occurrences validating a predicate.
cycle (t, n)Iterates through a table and loops n times.
map (t, f[, ...])Maps function f(key, value) on all key-value pairs.
reduce (t, f[, state])Reduces a table, left-to-right.
reduceRight (t, f[, state])Reduces a table, right-to-left.
mapReduce (t, f[, state])Reduces a table while saving intermediate states.
mapReduceRight (t, f[, state])Reduces a table while saving intermediate states.
include (t, value)Search for a value in a table.
detect (t, value)Search for a value in a table.
contains (t, value)Checks if a value is present in a table.
findWhere (t, props)Returns the first value having specified keys props.
select (t, f[, ...])Selects and extracts values passing an iterator test.
reject (t, f[, ...])Clones a table while dropping values passing an iterator test.
all (t, f[, ...])Checks if all values in a table are passing an iterator test.
invoke (t, method[, ...])Invokes a method on each value in a table.
pluck (t, a)Extracts property-values from a table of values.
max (t[, transform[, ...]])Returns the max value in a collection.
min (t[, transform[, ...]])Returns the min value in a collection.
shuffle (t[, seed])Returns a shuffled copy of a given collection.
same (a, b)Checks if two tables are the same.
sort (t[, comp])Sorts a table, in-place.
groupBy (t, iter[, ...])Splits a table into subsets.
countBy (t, iter[, ...])Groups values in a collection and counts them.
size ([...])Counts the number of values in a collection.
containsKeys (t, other)Checks if all the keys of other table exists in table t.
sameKeys (tA, tB)Checks if both given tables have the same keys.
+

Array functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
toArray ([...])Converts a vararg list to an array-list.
find (array, value[, from])Looks for the first occurrence of a given value in an array.
reverse (array)Reverses values in a given array.
selectWhile (array, f[, ...])Collects values from a given array.
dropWhile (array, f[, ...])Collects values from a given array.
sortedIndex (array, the[, comp[, sort]])Returns the index at which a value should be inserted.
indexOf (array, the)Returns the index of a given value in an array.
lastIndexOf (array, the)Returns the index of the last occurrence of a given value.
addTop (array, ...)Adds all passed-in values at the top of an array.
push (array, ...)Pushes all passed-in values at the end of an array.
pop (array[, n])Removes and returns the values at the top of a given array.
unshift (array[, n])Removes and returns the values at the end of a given array.
pull (array, ...)Removes all provided values in a given array.
removeRange (array[, start[, finish]])Trims all values indexed within the range [start, finish].
chunk (array, f[, ...])Chunks together consecutive values.
slice (array[, start[, finish]])Slices values indexed within [start, finish] range.
first (array[, n])Returns the first N values in an array.
initial (array[, n])Returns all values in an array excluding the last N values.
last (array[, n])Returns the last N values in an array.
rest (array[, index])Trims all values before index.
compact (array)Trims all falsy (false and nil) values.
flatten (array[, shallow])Flattens a nested array.
difference (array, another)Returns values from an array not present in all passed-in args.
union (...)Returns the duplicate-free union of all passed in arrays.
intersection (array, ...)Returns the intersection of all passed-in arrays.
symmetricDifference (array, array2)Performs a symmetric difference.
unique (array)Produces a duplicate-free version of a given array.
isunique (array)Checks if a given array contains distinct values.
zip (...)Merges values of each of the passed-in arrays in subsets.
append (array, other)Clones array and appends other values.
interleave (...)Interleaves arrays.
interpose (value, array)Interposes value in-between consecutive pair of values in array.
range ([from[, to[, step]]])Produce a flexible list of numbers.
rep (value, n)Creates an array list of n values, repeated.
partition. (array[, n])Iterator returning partitions of an array.
permutation (array)Iterator returning the permutations of an array.
invert (array)Swaps keys with values.
concat (array[, sep[, i[, j]]])Concatenates values in a given array.
+

Utility functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
identity (value)Returns the passed-in value.
once (f)Returns a version of f that runs only once.
memoize (f[, hash])Memoizes a given function by caching the computed result.
after (f, count)Returns a version of f that runs on the count-th call.
compose (...)Composes functions.
pipe (value, ...)Pipes a value through a series of functions.
complement (f)Returns the logical complement of a given function.
juxtapose (value, ...)Calls a sequence of passed-in functions with the same argument.
wrap (f, wrapper)Wraps f inside of the wrapper function.
times (n, iter, ...)Runs iter function n times.
bind (f, v)Binds v to be the first argument to function f.
bindn (f, ...)Binds ... to be the N-first arguments to function f.
uniqueId ([template[, ...]])Generates a unique ID for the current session.
+

Object functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
keys (obj)Returns the keys of the object properties.
values (obj)Returns the values of the object properties.
toBoolean (value)Converts any given value to a boolean
extend (destObj, ...)Extends an object properties.
functions ([obj])Returns a sorted list of all methods names found in an object.
clone (obj[, shallow])Clones a given object properties.
tap (obj, f[, ...])Invokes interceptor with the object, and then returns object.
has (obj, key)Checks if a given object implements a property.
pick (obj, ...)Return a filtered copy of the object.
omit (obj, ...)Return a filtered copy of the object.
template (obj[, template])Fills nil properties in an object with the given template object.
isEqual (objA, objB[, useMt])Performs a deep comparison test between two objects.
result (obj, method[, ...])Invokes an object method.
isTable (t)Checks if the given arg is a table.
isCallable (obj)Checks if the given argument is an callable.
isArray (obj)Checks if the given argument is an array.
isIterable (obj)Checks if the given object is iterable with pairs (or ipairs ).
isEmpty ([obj])Checks if the given is empty.
isString (obj)Checks if the given argument is a string.
isFunction (obj)Checks if the given argument is a function.
isNil (obj)Checks if the given argument is nil.
isNumber (obj)Checks if the given argument is a number.
isNaN (obj)Checks if the given argument is NaN (see Not-A-Number).
isFinite (obj)Checks if the given argument is a finite number.
isBoolean (obj)Checks if the given argument is a boolean.
isInteger (obj)Checks if the given argument is an integer.
chain (value)Returns a wrapped object.
obj:value ()Extracts the value of a wrapped object.
import ([context[, noConflict]])Imports all library functions into a context.
+ +
+
+ + +

Table functions

+ +
+
+ + each (t, f[, ...]) +
+
+ Iterates on each key-value pairs in a table. Calls function f(key, value) at each step of iteration. +
Aliased as forEach. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ + + +

See also:

+ + + +
+
+ + eachi (t, f[, ...]) +
+
+ Iterates on each integer key-value pairs in a table. Calls function f(key, value) + only on values at integer key in a given collection. The table can be a sparse array, + or map-like. Iteration will start from the lowest integer key found to the highest one. +
Aliased as forEachi. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ + + +

See also:

+ + + +
+
+ + at (t, ...) +
+
+ Returns an array of values at specific indexes and keys. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • ... + vararg + A variable number of indexes or keys to extract values +
  • +
+ +

Returns:

+
    + + table + an array-list of values from the passed-in table +
+ + + + +
+
+ + count (t[, value]) +
+
+ Counts occurrences of a given value in a table. Uses isEqual to compare values. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • value + value + a value to be searched in the table. If not given, the size of the table will be returned +
  • +
+ +

Returns:

+
    + + number + the count of occurrences of value +
+ + +

See also:

+ + + +
+
+ + countf (t, f[, ...]) +
+
+ Counts occurrences validating a predicate. Same as count, but uses an iterator. + Returns the count for values passing the test f(key, value, ...) + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ +

Returns:

+
    + + number + the count of values validating the predicate +
+ + +

See also:

+ + + +
+
+ + cycle (t, n) +
+
+ Iterates through a table and loops n times. The full iteration loop will be + repeated n times (or forever, if n is omitted). In case n is lower or equal to 0, it returns + an empty function. +
Aliased as loop. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • n + number + the number of loops +
  • +
+ +

Returns:

+
    + + function + an iterator function yielding key-value pairs from the passed-in table. +
+ + + + +
+
+ + map (t, f[, ...]) +
+
+ Maps function f(key, value) on all key-value pairs. Collects + and returns the results as a table. +
Aliased as collect. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ +

Returns:

+
    + + table + a table of results +
+ + + + +
+
+ + reduce (t, f[, state]) +
+
+ Reduces a table, left-to-right. Folds the table from the first element to the last element + to into a single value, with respect to a given iterator and an initial state. + The given function takes a state and a value and returns a new state. +
Aliased as inject, foldl. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(state, value) +
  • +
  • state + state + an initial state of reduction. Defaults to the first value in the table. +
  • +
+ +

Returns:

+
    + + state + state the final state of reduction +
+ + +

See also:

+ + + +
+
+ + reduceRight (t, f[, state]) +
+
+ Reduces a table, right-to-left. Folds the table from the last element to the first element + to single value, with respect to a given iterator and an initial state. + The given function takes a state and a value, and returns a new state. +
Aliased as injectr, foldr. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(state,value) +
  • +
  • state + state + an initial state of reduction. Defaults to the last value in the table. +
  • +
+ +

Returns:

+
    + + state + state the final state of reduction +
+ + +

See also:

+ + + +
+
+ + mapReduce (t, f[, state]) +
+
+ Reduces a table while saving intermediate states. Folds the table left-to-right + to a single value, with respect to a given iterator and an initial state. The given function + takes a state and a value, and returns a new state. It returns an array of intermediate states. +
Aliased as mapr + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(state, value) +
  • +
  • state + state + an initial state of reduction. Defaults to the first value in the table. +
  • +
+ +

Returns:

+
    + + table + an array of states +
+ + +

See also:

+ + + +
+
+ + mapReduceRight (t, f[, state]) +
+
+ Reduces a table while saving intermediate states. Folds the table right-to-left + to a single value, with respect to a given iterator and an initial state. The given function + takes a state and a value, and returns a new state. It returns an array of intermediate states. +
Aliased as maprr + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(state,value) +
  • +
  • state + state + an initial state of reduction. Defaults to the last value in the table. +
  • +
+ +

Returns:

+
    + + table + an array of states +
+ + +

See also:

+ + + +
+
+ + include (t, value) +
+
+ Search for a value in a table. It does not search in nested tables. +
Aliased as any, some + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • value + value or function + a value to search for +
  • +
+ +

Returns:

+
    + + boolean + a boolean : true when found, false otherwise +
+ + +

See also:

+ + + +
+
+ + detect (t, value) +
+
+ Search for a value in a table. Returns the key of the value if found. + It does not search in nested tables. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • value + value + a value to search for +
  • +
+ +

Returns:

+
    + + key + the value key or nil +
+ + +

See also:

+ + + +
+
+ + contains (t, value) +
+
+ Checks if a value is present in a table. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • value + value + a value to search for +
  • +
+ +

Returns:

+
    + + boolean + true if present, otherwise false +
+ + +

See also:

+ + + +
+
+ + findWhere (t, props) +
+
+ Returns the first value having specified keys props. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • props + table + a set of keys +
  • +
+ +

Returns:

+
    + + value + a value from the passed-in table +
+ + + + +
+
+ + select (t, f[, ...]) +
+
+ Selects and extracts values passing an iterator test. +
Aliased as filter. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ +

Returns:

+
    + + table + the selected values +
+ + +

See also:

+ + + +
+
+ + reject (t, f[, ...]) +
+
+ Clones a table while dropping values passing an iterator test. +
Aliased as discard + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ +

Returns:

+
    + + table + the remaining values +
+ + +

See also:

+ + + +
+
+ + all (t, f[, ...]) +
+
+ Checks if all values in a table are passing an iterator test. +
Aliased as every + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • f + function + an iterator function, prototyped as f(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ +

Returns:

+
    + + boolean + true if all values passes the predicate, false otherwise +
+ + + + +
+
+ + invoke (t, method[, ...]) +
+
+ Invokes a method on each value in a table. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • method + function + a function, prototyped as f(value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function method +
  • +
+ +

Returns:

+
    + + result + the result(s) of method call f(value, ...) +
+ + +

See also:

+ + + +
+
+ + pluck (t, a) +
+
+ Extracts property-values from a table of values. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • a + string + property, will be used to index in each value: value[property] +
  • +
+ +

Returns:

+
    + + table + an array of values for the specified property +
+ + + + +
+
+ + max (t[, transform[, ...]]) +
+
+ Returns the max value in a collection. If an transformation function is passed, it will + be used to extract the value by which all objects will be sorted. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • transform + function + an transformation function, prototyped as transform(value,...), defaults to identity +
  • +
  • ... + vararg + Optional extra-args to be passed to function transform +
  • +
+ +

Returns:

+
    + + value + the maximum value found +
+ + +

See also:

+ + + +
+
+ + min (t[, transform[, ...]]) +
+
+ Returns the min value in a collection. If an transformation function is passed, it will + be used to extract the value by which all objects will be sorted. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • transform + function + an transformation function, prototyped as transform(value,...), defaults to identity +
  • +
  • ... + vararg + Optional extra-args to be passed to function transform +
  • +
+ +

Returns:

+
    + + value + the minimum value found +
+ + +

See also:

+ + + +
+
+ + shuffle (t[, seed]) +
+
+ Returns a shuffled copy of a given collection. If a seed is provided, it will + be used to init the random number generator (via math.randomseed ). + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • seed + number + a seed +
  • +
+ +

Returns:

+
    + + table + a shuffled copy of the given table +
+ + + + +
+
+ + same (a, b) +
+
+ Checks if two tables are the same. It compares if both tables features the same values, + but not necessarily at the same keys. + +

Parameters:

+
    +
  • a + table + a table +
  • +
  • b + table + another table +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + sort (t[, comp]) +
+
+ Sorts a table, in-place. If a comparison function is given, it will be used to sort values. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • comp + function + a comparison function prototyped as comp(a,b), defaults to < operator. +
  • +
+ +

Returns:

+
    + + table + the given table, sorted. +
+ + + + +
+
+ + groupBy (t, iter[, ...]) +
+
+ Splits a table into subsets. Each subset feature values from the original table grouped + by the result of passing it through an iterator. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • iter + function + an iterator function, prototyped as iter(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function iter +
  • +
+ +

Returns:

+
    + + table + a new table with values grouped by subsets +
+ + + + +
+
+ + countBy (t, iter[, ...]) +
+
+ Groups values in a collection and counts them. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • iter + function + an iterator function, prototyped as iter(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function iter +
  • +
+ +

Returns:

+
    + + table + a new table with subsets names paired with their count +
+ + + + +
+
+ + size ([...]) +
+
+ Counts the number of values in a collection. If being passed more than one args + it will return the count of all passed-in args. + +

Parameters:

+
    +
  • ... + vararg + Optional variable number of arguments +
  • +
+ +

Returns:

+
    + + number + a count +
+ + +

See also:

+ + + +
+
+ + containsKeys (t, other) +
+
+ Checks if all the keys of other table exists in table t. It does not + compares values. The test is not commutative, i.e table t may contains keys + not existing in other. + +

Parameters:

+
    +
  • t + table + a table +
  • +
  • other + table + another table +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + +

See also:

+ + + +
+
+ + sameKeys (tA, tB) +
+
+ Checks if both given tables have the same keys. It does not compares values. + +

Parameters:

+
    +
  • tA + table + a table +
  • +
  • tB + table + another table +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + +

See also:

+ + + +
+
+

Array functions

+ +
+
+ + toArray ([...]) +
+
+ Converts a vararg list to an array-list. + +

Parameters:

+
    +
  • ... + vararg + Optional variable number of arguments +
  • +
+ +

Returns:

+
    + + table + an array-list of all passed-in args +
+ + + + +
+
+ + find (array, value[, from]) +
+
+ Looks for the first occurrence of a given value in an array. Returns the value index if found. + +

Parameters:

+
    +
  • array + table + an array of values +
  • +
  • value + value + a value to search for +
  • +
  • from + number + the index from where to start the search. Defaults to 1. +
  • +
+ +

Returns:

+
    + + number or nil + the index of the value if found in the array, nil otherwise. +
+ + + + +
+
+ + reverse (array) +
+
+ Reverses values in a given array. The passed-in array should not be sparse. + +

Parameters:

+
    +
  • array + table + an array +
  • +
+ +

Returns:

+
    + + table + a copy of the given array, reversed +
+ + + + +
+
+ + selectWhile (array, f[, ...]) +
+
+ Collects values from a given array. The passed-in array should not be sparse. + This function collects values as long as they satisfy a given predicate. + Therefore, it returns on the first falsy test. +
Aliased as takeWhile + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • f + function + an iterator function prototyped as f(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ +

Returns:

+
    + + table + a new table containing all values collected +
+ + +

See also:

+ + + +
+
+ + dropWhile (array, f[, ...]) +
+
+ Collects values from a given array. The passed-in array should not be sparse. + This function collects values as long as they do not satisfy a given predicate. + Therefore it returns on the first true test. +
Aliased as rejectWhile + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • f + function + an iterator function prototyped as f(key,value,...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ +

Returns:

+
    + + table + a new table containing all values collected +
+ + + + +
+
+ + sortedIndex (array, the[, comp[, sort]]) +
+
+ Returns the index at which a value should be inserted. This returned index is determined so + that it maintains the sort. If a comparison function is passed, it will be used to sort all + values. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • the + value + value to be inserted +
  • +
  • comp + function + an comparison function prototyped as f(a, b), defaults to < operator. +
  • +
  • sort + boolean + whether or not the passed-in array should be sorted +
  • +
+ +

Returns:

+
    + + number + the index at which the passed-in value should be inserted +
+ + + + +
+
+ + indexOf (array, the) +
+
+ Returns the index of a given value in an array. If the passed-in value exists + more than once in the array, it will return the index of the first occurrence. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • the + value + value to search for +
  • +
+ +

Returns:

+
    + + number or nil + the index of the passed-in value +
+ + +

See also:

+ + + +
+
+ + lastIndexOf (array, the) +
+
+ Returns the index of the last occurrence of a given value. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • the + value + value to search for +
  • +
+ +

Returns:

+
    + + number or nil + the index of the last occurrence of the passed-in value or nil +
+ + +

See also:

+ + + +
+
+ + addTop (array, ...) +
+
+ Adds all passed-in values at the top of an array. The last arguments will bubble to the + top of the given array. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • ... + vararg + a variable number of arguments +
  • +
+ +

Returns:

+
    + + table + the passed-in array +
+ + +

See also:

+ + + +
+
+ + push (array, ...) +
+
+ Pushes all passed-in values at the end of an array. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • ... + vararg + a variable number of arguments +
  • +
+ +

Returns:

+
    + + table + the passed-in array +
+ + +

See also:

+ + + +
+
+ + pop (array[, n]) +
+
+ Removes and returns the values at the top of a given array. +
Aliased as shift + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • n + number + the number of values to be popped. Defaults to 1. +
  • +
+ +

Returns:

+
    + + vararg + a vararg list of values popped from the array +
+ + +

See also:

+ + + +
+
+ + unshift (array[, n]) +
+
+ Removes and returns the values at the end of a given array. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • n + number + the number of values to be unshifted. Defaults to 1. +
  • +
+ +

Returns:

+
    + + vararg + a vararg list of values +
+ + +

See also:

+ + + +
+
+ + pull (array, ...) +
+
+ Removes all provided values in a given array. +
Aliased as remove + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • ... + vararg + a variable number of values to be removed from the array +
  • +
+ +

Returns:

+
    + + table + the passed-in array +
+ + + + +
+
+ + removeRange (array[, start[, finish]]) +
+
+ Trims all values indexed within the range [start, finish]. +
Aliased as rmRange + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • start + number + the lower bound index, defaults to the first index in the array. +
  • +
  • finish + number + the upper bound index, defaults to the array length. +
  • +
+ +

Returns:

+
    + + table + the passed-in array +
+ + + + +
+
+ + chunk (array, f[, ...]) +
+
+ Chunks together consecutive values. Values are chunked on the basis of the return + value of a provided predicate f(key, value, ...). Consecutive elements which return + the same value are chunked together. Leaves the first argument untouched if it is not an array. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • f + function + an iterator function prototyped as f(key, value, ...) +
  • +
  • ... + vararg + Optional extra-args to be passed to function f +
  • +
+ +

Returns:

+
    + + table + a table of chunks (arrays) +
+ + +

See also:

+ + + +
+
+ + slice (array[, start[, finish]]) +
+
+ Slices values indexed within [start, finish] range. +
Aliased as _.sub + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • start + number + the lower bound index, defaults to the first index in the array. +
  • +
  • finish + number + the upper bound index, defaults to the array length. +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + + + +
+
+ + first (array[, n]) +
+
+ Returns the first N values in an array. +
Aliased as head, take + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • n + number + the number of values to be collected, defaults to 1. +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + initial (array[, n]) +
+
+ Returns all values in an array excluding the last N values. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • n + number + the number of values to be left, defaults to the array length. +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + last (array[, n]) +
+
+ Returns the last N values in an array. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • n + number + the number of values to be collected, defaults to the array length. +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + rest (array[, index]) +
+
+ Trims all values before index. +
Aliased as tail + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • index + number + an index, defaults to 1 +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + compact (array) +
+
+ Trims all falsy (false and nil) values. + +

Parameters:

+
    +
  • array + table + an array +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + + + +
+
+ + flatten (array[, shallow]) +
+
+ Flattens a nested array. Passing shallow will only flatten at the first level. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • shallow + boolean + specifies the flattening depth +
  • +
+ +

Returns:

+
    + + table + a new array, flattened +
+ + + + +
+
+ + difference (array, another) +
+
+ Returns values from an array not present in all passed-in args. +
Aliased as without and diff + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • another + table + array +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + union (...) +
+
+ Returns the duplicate-free union of all passed in arrays. + +

Parameters:

+
    +
  • ... + vararg + a variable number of arrays arguments +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + intersection (array, ...) +
+
+ Returns the intersection of all passed-in arrays. + Each value in the result is present in each of the passed-in arrays. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • ... + vararg + a variable number of array arguments +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + symmetricDifference (array, array2) +
+
+ Performs a symmetric difference. Returns values from array not present in array2 and also values + from array2 not present in array. +
Aliased as symdiff + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • array2 + table + another array +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + unique (array) +
+
+ Produces a duplicate-free version of a given array. +
Aliased as uniq + +

Parameters:

+
    +
  • array + table + an array +
  • +
+ +

Returns:

+
    + + table + a new array, duplicate-free +
+ + +

See also:

+ + + +
+
+ + isunique (array) +
+
+ Checks if a given array contains distinct values. Such an array is made of distinct elements, + which only occur once in this array. +
Aliased as isuniq + +

Parameters:

+
    +
  • array + table + an array +
  • +
+ +

Returns:

+
    + + boolean + true if the given array is unique, false otherwise. +
+ + +

See also:

+ + + +
+
+ + zip (...) +
+
+ Merges values of each of the passed-in arrays in subsets. + Only values indexed with the same key in the given arrays are merged in the same subset. + +

Parameters:

+
    +
  • ... + vararg + a variable number of array arguments +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + + + +
+
+ + append (array, other) +
+
+ Clones array and appends other values. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • other + table + an array +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + + + +
+
+ + interleave (...) +
+
+ Interleaves arrays. It returns a single array made of values from all + passed in arrays in their given order, interleaved. + +

Parameters:

+
    +
  • ... + vararg + a variable list of arrays +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + interpose (value, array) +
+
+ Interposes value in-between consecutive pair of values in array. + +

Parameters:

+
    +
  • value + value + a value +
  • +
  • array + table + an array +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + +

See also:

+ + + +
+
+ + range ([from[, to[, step]]]) +
+
+ Produce a flexible list of numbers. If one positive value is passed, will count from 0 to that value, + with a default step of 1. If two values are passed, will count from the first one to the second one, with the + same default step of 1. A third passed value will be considered a step value. + +

Parameters:

+
    +
  • from + number + the initial value of the range +
  • +
  • to + number + the final value of the range +
  • +
  • step + number + the count step value +
  • +
+ +

Returns:

+
    + + table + a new array of numbers +
+ + + + +
+
+ + rep (value, n) +
+
+ Creates an array list of n values, repeated. + +

Parameters:

+
    +
  • value + value + a value to be repeated +
  • +
  • n + number + the number of repetitions of the given value. +
  • +
+ +

Returns:

+
    + + table + a new array of n values +
+ + + + +
+
+ + partition. (array[, n]) +
+
+ Iterator returning partitions of an array. It returns arrays of length n + made of values from the given array. In case the array size is not a multiple + of n, the last array returned will be made of the rest of the values. + +

Parameters:

+
    +
  • array + table + an array +
  • +
  • n + number + the size of each partition. Defaults to 1. +
  • +
+ +

Returns:

+
    + + function + an iterator function +
+ + + + +
+
+ + permutation (array) +
+
+ Iterator returning the permutations of an array. It returns arrays made of all values + from the passed-in array, with values permuted. + +

Parameters:

+
    +
  • array + table + an array +
  • +
+ +

Returns:

+
    + + function + an iterator function +
+ + + + +
+
+ + invert (array) +
+
+ Swaps keys with values. Produces a new array where previous keys are now values, + while previous values are now keys. +
Aliased as mirror + +

Parameters:

+
    +
  • array + table + a given array +
  • +
+ +

Returns:

+
    + + table + a new array +
+ + + + +
+
+ + concat (array[, sep[, i[, j]]]) +
+
+ Concatenates values in a given array. Handles booleans as well. If sep string is + passed, it will be used as a separator. Passing i and j will result in concatenating + values within [i,j] range. +
Aliased as join + +

Parameters:

+
    +
  • array + table + a given array +
  • +
  • sep + string + a separator string, defaults to ''. +
  • +
  • i + number + the starting index, defaults to 1. +
  • +
  • j + number + the final index, defaults to the array length. +
  • +
+ +

Returns:

+
    + + string + a string +
+ + + + +
+
+

Utility functions

+ +
+
+ + identity (value) +
+
+ Returns the passed-in value. This function seems useless, but it is used internally + as a default iterator. + +

Parameters:

+
    +
  • value + value + a value +
  • +
+ +

Returns:

+
    + + value + the passed-in value +
+ + + + +
+
+ + once (f) +
+
+ Returns a version of f that runs only once. Successive calls to f + will keep yielding the same output, no matter what the passed-in arguments are. + It can be used to initialize variables. + +

Parameters:

+
    +
  • f + function + a function +
  • +
+ +

Returns:

+
    + + function + a new function +
+ + +

See also:

+ + + +
+
+ + memoize (f[, hash]) +
+
+ Memoizes a given function by caching the computed result. + Useful for speeding-up slow-running functions. If function hash is passed, + it will be used to compute hash keys for a set of input values to the function for caching. +
Aliased as cache + +

Parameters:

+
    +
  • f + function + a function +
  • +
  • hash + function + a hash function, defaults to identity +
  • +
+ +

Returns:

+
    + + function + a new function +
+ + + + +
+
+ + after (f, count) +
+
+ Returns a version of f that runs on the count-th call. + Useful when dealing with asynchronous tasks. + +

Parameters:

+
    +
  • f + function + a function +
  • +
  • count + number + the number of calls before f answers +
  • +
+ +

Returns:

+
    + + function + a new function +
+ + +

See also:

+ + + +
+
+ + compose (...) +
+
+ Composes functions. Each passed-in function consumes the return value of the function that follows. + In math terms, composing the functions f, g, and h produces the function f(g(h(...))). + +

Parameters:

+
    +
  • ... + vararg + a variable number of functions +
  • +
+ +

Returns:

+
    + + function + a new function +
+ + +

See also:

+ + + +
+
+ + pipe (value, ...) +
+
+ Pipes a value through a series of functions. In math terms, + given some functions f, g, and h in that order, it returns f(g(h(value))). + +

Parameters:

+
    +
  • value + value + a value +
  • +
  • ... + vararg + a variable number of functions +
  • +
+ +

Returns:

+
    + + value + the result of the composition of function calls. +
+ + +

See also:

+ + + +
+
+ + complement (f) +
+
+ Returns the logical complement of a given function. For a given input, the returned + function will output false if the original function would have returned true, + and vice-versa. + +

Parameters:

+
    +
  • f + function + a function +
  • +
+ +

Returns:

+
    + + function + the logical complement of the given function f. +
+ + + + +
+
+ + juxtapose (value, ...) +
+
+ Calls a sequence of passed-in functions with the same argument. + Returns a sequence of results. +
Aliased as juxt + +

Parameters:

+
    +
  • value + value + a value +
  • +
  • ... + vararg + a variable number of functions +
  • +
+ +

Returns:

+
    + + vararg + a vargarg list of results. +
+ + + + +
+
+ + wrap (f, wrapper) +
+
+ Wraps f inside of the wrapper function. It passes f as the first argument to wrapper. + This allows the wrapper to execute code before and after f runs, + adjust the arguments, and execute it conditionally. + +

Parameters:

+
    +
  • f + function + a function to be wrapped, prototyped as f(...) +
  • +
  • wrapper + function + a wrapper function, prototyped as wrapper(f,...) +
  • +
+ +

Returns:

+
    + + function + a new function +
+ + + + +
+
+ + times (n, iter, ...) +
+
+ Runs iter function n times. + Collects the results of each run and returns them in an array. + +

Parameters:

+
    +
  • n + number + the number of times iter should be called +
  • +
  • iter + function + an iterator function, prototyped as iter(i, ...) +
  • +
  • ... + vararg + extra-args to be passed to iter function +
  • +
+ +

Returns:

+
    + + table + an array of results +
+ + + + +
+
+ + bind (f, v) +
+
+ Binds v to be the first argument to function f. As a result, + calling f(...) will result to f(v, ...). + +

Parameters:

+
    +
  • f + function + a function +
  • +
  • v + value + a value +
  • +
+ +

Returns:

+
    + + function + a function +
+ + +

See also:

+ + + +
+
+ + bindn (f, ...) +
+
+ Binds ... to be the N-first arguments to function f. As a result, + calling f(a1, a2, ..., aN) will result to f(..., a1, a2, ...,aN). + +

Parameters:

+
    +
  • f + function + a function +
  • +
  • ... + vararg + a variable number of arguments +
  • +
+ +

Returns:

+
    + + function + a function +
+ + +

See also:

+ + + +
+
+ + uniqueId ([template[, ...]]) +
+
+ Generates a unique ID for the current session. If given a string template + will use this template for output formatting. Otherwise, if template is a function, + will evaluate template(id, ...). +
Aliased as uid. + +

Parameters:

+
    +
  • template + string or function + either a string or a function template to format the ID +
  • +
  • ... + vararg + a variable number of arguments to be passed to template, in case it is a function. +
  • +
+ +

Returns:

+
    + + value + an ID +
+ + + + +
+
+

Object functions

+ +
+
+ + keys (obj) +
+
+ Returns the keys of the object properties. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
+ +

Returns:

+
    + + table + an array +
+ + + + +
+
+ + values (obj) +
+
+ Returns the values of the object properties. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
+ +

Returns:

+
    + + table + an array +
+ + + + +
+
+ + toBoolean (value) +
+
+ Converts any given value to a boolean + +

Parameters:

+
    +
  • value + value + a value. Can be of any type +
  • +
+ +

Returns:

+
    + + boolean + true if value is true, false otherwise (false or nil). +
+ + + + +
+
+ + extend (destObj, ...) +
+
+ Extends an object properties. It copies all of the properties of extra passed-in objects + into the destination object, and returns the destination object. + The last object in the ... set will override properties of the same name in the previous one + +

Parameters:

+
    +
  • destObj + table + a destination object +
  • +
  • ... + vararg + a variable number of array arguments +
  • +
+ +

Returns:

+
    + + table + the destination object extended +
+ + + + +
+
+ + functions ([obj]) +
+
+ Returns a sorted list of all methods names found in an object. If the given object + has a metatable implementing an __index field pointing to another table, will also recurse on this + table if argument recurseMt is provided. If obj is omitted, it defaults to the library functions. +
Aliased as methods. + +

Parameters:

+
    +
  • obj + table + an object. Defaults to library functions. +
  • +
+ +

Returns:

+
    + + table + an array-list of methods names +
+ + + + +
+
+ + clone (obj[, shallow]) +
+
+ Clones a given object properties. If shallow is passed + will also clone nested array properties. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
  • shallow + boolean + whether or not nested array-properties should be cloned, defaults to false. +
  • +
+ +

Returns:

+
    + + table + a copy of the passed-in object +
+ + + + +
+
+ + tap (obj, f[, ...]) +
+
+ Invokes interceptor with the object, and then returns object. + The primary purpose of this method is to "tap into" a method chain, in order to perform operations + on intermediate results within the chain. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
  • f + function + an interceptor function, should be prototyped as f(obj, ...) +
  • +
  • ... + vararg + Extra-args to be passed to interceptor function +
  • +
+ +

Returns:

+
    + + table + the passed-in object +
+ + + + +
+
+ + has (obj, key) +
+
+ Checks if a given object implements a property. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
  • key + value + a key property to be checked +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + pick (obj, ...) +
+
+ Return a filtered copy of the object. The returned object will only have + the white-listed properties paired with their original values. +
Aliased as choose. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
  • ... + vararg + a variable number of string keys +
  • +
+ +

Returns:

+
    + + table + the filtered object +
+ + + + +
+
+ + omit (obj, ...) +
+
+ Return a filtered copy of the object. The returned object will not have + the black-listed properties. +
Aliased as drop. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
  • ... + vararg + a variable number of string keys +
  • +
+ +

Returns:

+
    + + table + the filtered object +
+ + + + +
+
+ + template (obj[, template]) +
+
+ Fills nil properties in an object with the given template object. Pre-existing + properties will be preserved. +
Aliased as defaults. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
  • template + table + a template object. Defaults to an empty table {}. +
  • +
+ +

Returns:

+
    + + table + the passed-in object filled +
+ + + + +
+
+ + isEqual (objA, objB[, useMt]) +
+
+ Performs a deep comparison test between two objects. Can compare strings, functions + (by reference), nil, booleans. Compares tables by reference or by values. If useMt + is passed, the equality operator == will be used if one of the given objects has a + metatable implementing __eq. +
Aliased as _.compare + +

Parameters:

+
    +
  • objA + table + an object +
  • +
  • objB + table + another object +
  • +
  • useMt + boolean + whether or not __eq should be used, defaults to false. +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + result (obj, method[, ...]) +
+
+ Invokes an object method. It passes the object itself as the first argument. if method is not + callable, will return obj[method]. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
  • method + string + a string key to index in object obj. +
  • +
  • ... + vararg + Optional extra-args to be passed to method +
  • +
+ +

Returns:

+
    + + value + the returned value of method(obj,...) call +
+ + + + +
+
+ + isTable (t) +
+
+ Checks if the given arg is a table. + +

Parameters:

+
    +
  • t + table + a value to be tested +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + isCallable (obj) +
+
+ Checks if the given argument is an callable. Assumes obj is callable if + it is either a function or a table having a metatable implementing __call metamethod. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + isArray (obj) +
+
+ Checks if the given argument is an array. Assumes obj is an array + if is a table with integer numbers starting at 1. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + isIterable (obj) +
+
+ Checks if the given object is iterable with pairs (or ipairs ). + +

Parameters:

+
    +
  • obj + table + an object +
  • +
+ +

Returns:

+
    + + boolean + true if the object can be iterated with pairs , false otherwise +
+ + + + +
+
+ + isEmpty ([obj]) +
+
+ Checks if the given is empty. If obj is a string, will return true + if #obj == 0. Otherwise, if obj is a table, will return whether or not this table + is empty. If obj is nil, it will return true. + +

Parameters:

+ + +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + isString (obj) +
+
+ Checks if the given argument is a string. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + isFunction (obj) +
+
+ Checks if the given argument is a function. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + isNil (obj) +
+
+ Checks if the given argument is nil. + +

Parameters:

+
    +
  • obj + table + an object +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + isNumber (obj) +
+
+ Checks if the given argument is a number. + +

Parameters:

+
    +
  • obj + table + a number +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + +

See also:

+ + + +
+
+ + isNaN (obj) +
+
+ Checks if the given argument is NaN (see Not-A-Number). + +

Parameters:

+
    +
  • obj + table + a number +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + +

See also:

+ + + +
+
+ + isFinite (obj) +
+
+ Checks if the given argument is a finite number. + +

Parameters:

+
    +
  • obj + table + a number +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + isBoolean (obj) +
+
+ Checks if the given argument is a boolean. + +

Parameters:

+
    +
  • obj + table + a boolean +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + isInteger (obj) +
+
+ Checks if the given argument is an integer. + +

Parameters:

+
    +
  • obj + table + a number +
  • +
+ +

Returns:

+
    + + boolean + true or false +
+ + + + +
+
+ + chain (value) +
+
+ Returns a wrapped object. Calling library functions as methods on this object + will continue to return wrapped objects until obj:value is used. Can be aliased as _(value). + +

Parameters:

+
    +
  • value + value + a value to be wrapped +
  • +
+ +

Returns:

+
    + + object + a wrapped object +
+ + + + +
+
+ + obj:value () +
+
+ Extracts the value of a wrapped object. Must be called on an chained object (see chain). + + +

Returns:

+
    + + value + the value previously wrapped +
+ + + + +
+
+ + import ([context[, noConflict]]) +
+
+ Imports all library functions into a context. + +

Parameters:

+
    +
  • context + table + a context. Defaults to _G (global environment) when not given. +
  • +
  • noConflict + boolean + Skips function import in case its key exists in the given context +
  • +
+ +

Returns:

+
    + + table + the passed-in context +
+ + + + +
+
+ + +
+
+
+generated by LDoc 1.4.0 +
+
+ + diff --git a/files/docs/moses/ldoc.css b/files/docs/moses/ldoc.css new file mode 100644 index 0000000..ffcf750 --- /dev/null +++ b/files/docs/moses/ldoc.css @@ -0,0 +1,306 @@ +/* BEGIN RESET + +Copyright (c) 2010, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.8.2r1 +*/ +html { + color: #000; + background: #FFF; +} + +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { + margin: 0; + padding: 0; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +fieldset,img { + border: 0; +} +address,caption,cite,code,dfn,em,strong,th,var,optgroup { + font-style: inherit; + font-weight: inherit; +} +del,ins { + text-decoration: none; +} +li { + list-style: disc; + margin-left: 20px; +} +caption,th { + text-align: left; +} +h1,h2,h3,h4,h5,h6 { + font-size: 100%; + font-weight: bold; +} +q:before,q:after { + content: ''; +} +abbr,acronym { + border: 0; + font-variant: normal; +} +sup { + vertical-align: baseline; +} +sub { + vertical-align: baseline; +} +legend { + color: #000; +} +input,button,textarea,select,optgroup,option { + font-family: inherit; + font-size: inherit; + font-style: inherit; + font-weight: inherit; +} +input,button,textarea,select {*font-size:100%; +} +/* END RESET */ + +body { + margin-left: 1em; + margin-right: 1em; + font-family: arial, helvetica, geneva, sans-serif; + background-color: #ffffff; margin: 0px; +} + +code, tt { font-family: monospace; font-size: 1.1em; } +span.parameter { font-family:monospace; } +span.parameter:after { content:":"; } +span.types:before { content:"("; } +span.types:after { content:")"; } +.type { font-weight: bold; font-style:italic } + +body, p, td, th { font-size: .95em; line-height: 1.2em;} + +p, ul { margin: 10px 0 0 0px;} + +strong { font-weight: bold;} + +em { font-style: italic;} + +h1 { + font-size: 1.5em; + margin: 0 0 20px 0; +} +h2, h3, h4 { margin: 15px 0 10px 0; } +h2 { font-size: 1.25em; } +h3 { font-size: 1.15em; } +h4 { font-size: 1.06em; } + +a:link { font-weight: normal; color: #C147C1; text-decoration: none; } +a:visited { font-weight: normal; color: #C147C1; text-decoration: none; } +a:link:hover { text-decoration: underline; } + +hr { + color:#cccccc; + background: #00007f; + height: 1px; +} + +blockquote { margin-left: 3em; } + +ul { list-style-type: disc; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; +} + +pre.example { + background-color: rgb(245, 245, 245); + border: 1px solid silver; + padding: 10px; + margin: 10px 0 10px 0; + font-family: "Andale Mono", monospace; + font-size: .85em; +} + +pre { + background-color: rgb(245, 245, 245); + border: 1px solid silver; + padding: 10px; + margin: 10px 0 10px 0; + overflow: auto; + font-family: "Andale Mono", monospace; +} + + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } + +#container { + background-color: #f0f0f0; +} + +#product { + text-align: center; + background-color: #ffffff; +} + +#product big { + font-size: 2em; +} + +#main { + background: #5C3671 url(http://non2d.github.io/img/bg.png); + background-position-x: center; +} + +#navigation { + float: left; + width: 14em; + vertical-align: top; + overflow: visible; + color: white; +} + +#navigation h2, #content h2 { + display: none; +} + +#navigation h1 { + padding-left:0.4em; +} + +#navigation h2 { + font-size:1.1em; + padding:0.2em; +} + +#navigation ul +{ + font-size:1em; + list-style-type: none; + margin: 1px 1px 10px 1px; +} + +#navigation li { + text-indent: -1em; + display: block; + margin: 3px 0px 0px 22px; +} + +#navigation li li a { + margin: 0px 3px 0px -1em; +} + +#content { + margin-left: 14em; + padding: 1em; + width: 700px; + background-color: #fff; +} + +#about { + clear: both; + padding: 5px; + background: transparent; +} + +@media print { + body { + font: 12pt "Times New Roman", "TimeNR", Times, serif; + } + a { font-weight: bold; color: #004080; text-decoration: underline; } + + #main { + background-color: #ffffff; + border-left: 0px; + } + + #container { + margin-left: 2%; + margin-right: 2%; + background-color: #ffffff; + } + + #content { + padding: 1em; + background-color: #ffffff; + } + + #navigation { + display: none; + } + pre.example { + font-family: "Andale Mono", monospace; + font-size: 10pt; + page-break-inside: avoid; + } +} + +table.module_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.module_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.module_list td.name { background-color: #f0f0f0; min-width: 200px; } +table.module_list td.summary { width: 100%; } + + +table.function_list { + margin-top: 30px; + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.function_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.function_list td.name { background-color: #f0f0f0; min-width: 200px; } +table.function_list td.summary { width: 100%; } + +ul.nowrap { + overflow:auto; + white-space:nowrap; +} + +dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} +dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;} +dl.table h3, dl.function h3 {font-size: .95em;} + +/* stop sublists from having initial vertical space */ +ul ul { margin-top: 0px; } +ol ul { margin-top: 0px; } +ol ol { margin-top: 0px; } +ul ol { margin-top: 0px; } + +/* make the target distinct; helps when we're navigating to a function */ +a:target + * { + background-color: #FF9; +} + +/* styles for prettification of source */ +pre .comment { color: #558817; } +pre .constant { color: #a8660d; } +pre .escape { color: #844631; } +pre .keyword { color: #aa5050; font-weight: bold; } +pre .library { color: #0e7c6b; } +pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; } +pre .string { color: #8080ff; } +pre .number { color: #f8660d; } +pre .operator { color: #2239a8; font-weight: bold; } +pre .preprocessor, pre .prepro { color: #a33243; } +pre .global { color: #800080; } +pre .prompt { color: #558817; } +pre .url { color: #272fc2; text-decoration: underline; } \ No newline at end of file diff --git a/files/docs/moses/topics/tutorial.md.html b/files/docs/moses/topics/tutorial.md.html new file mode 100644 index 0000000..288eda2 --- /dev/null +++ b/files/docs/moses/topics/tutorial.md.html @@ -0,0 +1,1945 @@ + + + + + Moses documentation + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Topic tutorial.md

+ + Moses: a utility-belt library for Lua

+ +

Moses is a Lua utility library which provides support for functional programming. +It complements built-in Lua functions, making easier common operations on tables, arrays, lists, collections, objects, and a lot more.
+Moses was deeply inspired by Underscore.js.

+ +

Table of Contents

+ + + +

Drop the file moses.lua into your project and add it to your code with the require function:

+ + +
+local _ = require ("moses")
+
+ + +

Note: Lua purists tend to use "_" to design a "dummy variable". Here, the usage of this underscore is quite idiomatic and refers to the name Underscore, the JS library from which *Moses takes inspiration*.

+ +

[⬆]

+ +

Moses' API

+ +

Moses' consists of a large set of functions that can be classified into four categories:

+ +
    +
  • Table functions, which are mostly meant for tables, i.e Lua tables which contains both an array-part and/or a map-part,
  • +
  • Array functions, meant for array lists (or sequences),
  • +
  • Utility functions,
  • +
  • Object functions, meant for instances/classes.
  • +
+ +

[⬆]

+ +

+

Table functions

+ + +

each (t, f, ...)

+

*Aliases: _.forEach*.

+ +

Iterates over each key-value pair in table.

+ + +
+_.each({1,2,3},print)
+
+-- => 1 1
+-- => 2 2
+-- => 3 3
+
+
+ + +

The table can be map-like (array part and hash-part).

+ + +
+_.each({one = 1, two = 2, three = 3},print)
+
+-- => one 1
+-- => two 2
+-- => three 3
+
+
+ + +

Can index and assign in an outer table or in the passed-in table:

+ + +
+t = {'a','b','c'}
+_.each(t,function(i,v)
+  t[i] = v:rep(2)
+  print(t[i])
+end)
+
+-- => 1 aa
+-- => 2 bb
+-- => 3 cc
+
+
+ + +

eachi (t, f, ...)

+

*Aliases: _.forEachi*.

+ +

Iterates only on integer keys in a sparse array table.

+ + +
+_.eachi({1,2,3},print)
+
+-- => 1 1
+-- => 2 2
+-- => 3 3
+
+
+ + +

The given array can be sparse, or even have a hash-like part.

+ + +
+local t = {a = 1, b = 2, [0] = 1, [-1] = 6, 3, x = 4, 5}
+_.eachi(t,function(i,v)
+  print(i,v)
+end)
+
+-- => -1 6
+-- => 0 1
+-- => 1 3
+-- => 2 5
+
+
+ + +

at (t, ...)

+ +

Collects all values at some specific keys and returns them in an array.

+ + +
+local t = {4,5,6}
+_.at(t,1,3) -- => "{4,6}"
+
+local t = {a = 4, bb = true, ccc = false}
+_.at(t,'a', 'ccc') -- => "{4, false}"
+
+
+ + +

count (t, value)

+ +

Counts the number of occurences of a given value in a table.

+ + +
+_.count({1,1,2,3,3,3,2,4,3,2},1) -- => 2
+_.count({1,1,2,3,3,3,2,4,3,2},2) -- => 2
+_.count({1,1,2,3,3,3,2,4,3,2},3) -- => 4
+_.count({false, false, true},false) -- => 2
+_.count({false, false, true},true) -- => 1
+
+
+ + +

Returns the size of the list in case no value was provided.

+ + +
+_.count({1,1,2,3,3}) -- => 5
+
+
+ + +

countf (t, f, ...)

+ +

Count the number of occurences of all values passing an iterator test.

+ + +
+_.countf({1,2,3,4,5,6}, function(i,v)
+  return v%2==0
+end) -- => 3
+
+_.countf({print, pairs, os, assert, ipairs}, function(i,v)
+  return type(v)=='function'
+end) -- => 4
+
+
+ + +

cycle (t, n)

+

*Aliases: _.loop*.

+ +

Returns a function which iterates on each key-value pair in a given table (similarly to _.each), except that it restarts iterating again n times. +If n is not provided, it defaults to 1.

+ + +
+local t = {'a,'b','c'}
+for k,v in _.cycle(t, 2) do
+  print(k,v)
+end
+
+-- => 1 'a'
+-- => 2 'b'
+-- => 3 'c'
+-- => 1 'a'
+-- => 2 'b'
+-- => 3 'c'
+
+ + +

Supports array-like tables and map-like tables.

+ + +
+local t = {x = 1, y = 2, z = 3}
+for k,v in _.cycle(t) do
+  print(k,v)
+end
+
+-- => y    2
+-- => x 1
+-- => z 3
+
+
+ + +

map (t, f, ...)

+

*Aliases: _.collect*.

+ +

Executes a function on each key-value pairs.

+ + +
+_.map({1,2,3},function(i,v)
+  return v+10
+end)) -- => "{11,12,13}"
+
+
+ + + +
+_.map({a = 1, b = 2},function(k,v)
+  return k..v
+end) -- => "{a = 'a1', b = 'b2'}"
+
+
+ + +

reduce (t, f, state)

+

*Aliases: _.inject, _.foldl*.

+ +

Can sums all values in a table.

+ + +
+_.reduce({1,2,3,4},function(memo,v)
+  return memo+v
+end) -- => 10
+
+
+ + +

Or concatenates all values.

+ + +
+_.reduce({'a','b','c','d'},function(memo,v)
+  return memo..v
+end) -- => abcd
+
+
+ + +

reduceRight (t, f, state)

+

*Aliases: _.injectr, _.foldr*.

+ +

Similar to _.reduce, but performs from right to left.

+ + +
+local initial_state = 256
+_.reduceRight({1,2,4,16},function(memo,v)
+  return memo/v
+end,initial_state) -- => 2
+
+
+ + +

mapReduce (t, f, state)

+

*Aliases: _.mapr*.

+ +

Reduces while saving intermediate states.

+ + +
+_.mapReduce({'a','b','c'},function(memo,v)
+  return memo..v
+end) -- => "{'a', 'ab', 'abc'}"
+
+
+ + +

mapReduceRight (t, f, state)

+

*Aliases: _.maprr*.

+ +

Reduces from right to left, while saving intermediate states.

+ + +
+_.mapReduceRight({'a','b','c'},function(memo,v)
+  return memo..v
+end) -- => "{'c', 'cb', 'cba'}"
+
+
+ + +

include (t, value)

+

*Aliases: _.any, _.some*.

+ +

Looks for a value in a table.

+ + +
+_.include({6,8,10,16,29},16) -- => true
+_.include({6,8,10,16,29},1) -- => false
+
+local complex_table = {18,{2,{3}}}
+local collection = {6,{18,{2,6}},10,{18,{2,{3}}},29}
+_.include(collection, complex_table) -- => true
+
+
+ + +

Handles iterator functions.

+ + +
+local function isUpper(v) return v:upper()== v end
+_.include({'a','B','c'},isUpper) -- => true
+
+
+ + +

detect (t, value)

+ +

Returns the index of a value in a table.

+ + +
+_.detect({6,8,10,16},8) -- => 2
+_.detect({nil,true,0,true,true},false) -- => nil
+
+local complex_table = {18,{2,6}}
+local collection = {6,{18,{2,6}},10,{18,{2,{3}}},29}
+_.detect(collection, complex_table) -- => 2
+
+
+ + +

Handles iterator functions.

+ + +
+local function isUpper(v)
+  return v:upper()==v
+end
+_.detect({'a','B','c'},isUpper) -- => 2
+
+
+ + +

contains (t, value)

+ +

Returns true if the passed-in value was found in a given table.

+ + +
+_.contains({6,8,10,16},8) -- => true
+_.contains({nil,true,0,true,true},false) -- => false
+
+
+ + +

It can lookup for objects, and accepts iterator functions aswell:

+ + +
+_.contains({6,{18,{2,6}},10,{18,{2,{3}}},29},{18,{2,6}}) -- => true
+
+_.contains({'a','B','c'}, function(array_value)
+  return (array_value:upper() == array_value)
+end) -- => true
+
+
+ + +

findWhere (t, props)

+ +

Looks through a table and returns the first value that matches all of the key-value pairs listed in properties.

+ + +
+local a = {a = 1, b = 2, c = 3}
+local b = {a = 2, b = 3, d = 4}
+local c = {a = 3, b = 4, e = 5}
+_.findWhere({a, b, c}, {a = 3, b = 4}) == c -- => true
+
+
+ + +

select (t, f, ...)

+

*Aliases: _.filte*.

+ +

Collects values passing a validation test.

+ + +
+-- Even values
+_.select({1,2,3,4,5,6,7}, function(key,value)
+  return (value%2==0)
+end) -- => "{2,4,6}"
+
+-- Odd values
+_.select({1,2,3,4,5,6,7}, function(key,value)
+  return (value%2~=0)
+end) -- => "{1,3,5,7}"
+
+
+ + +

reject (t, f, ...)

+

*Aliases: _.reject*.

+ +

Removes all values failing a validation test:

+ + +
+_.reject({1,2,3,4,5,6,7}, function(key,value)
+  return (value%2==0)
+end) -- => "{1,3,5,7}"
+
+_.reject({1,2,3,4,5,6,7}, function(key,value)
+  return (value%2~=0)
+end) -- => "{2,4,6}"
+
+
+ + +

all (t, f, ...)

+

*Aliases: _.every*.

+ +

Checks whether or not all elements pass a validation test.

+ + +
+_.all({2,4,6}, function(key,value)
+  return (value%2==0)
+end) -- => true
+
+
+ + +

invoke (t, method, ...)

+ +

Invokes a given function on each value in a table

+ + +
+_.invoke({'a','bea','cdhza'},string.len) -- => "{1,3,5}"
+
+
+ + +

Can reference the method of the same name in each value.

+ + +
+local a = {}
+function a:call() return 'a' end
+local b, c, d = {}, {}, {}
+b.call, c.call, d.call = a.call, a.call, a.call
+
+_.invoke({a,b,c,d},'call') -- => "{'a','a','a','a'}"
+
+
+ + +

pluck (t, property)

+ +

Fetches all values indxed with specific key in a table of objects.

+ + +
+local peoples = {
+  {name = 'John', age = 23},{name = 'Peter', age = 17},
+  {name = 'Steve', age = 15},{age = 33}}
+
+_.pluck(peoples,'age') -- => "{23,17,15,33}"
+_.pluck(peoples,'name') -- => "{'John', 'Peter', 'Steve'}"
+
+
+ + +

max (t, transform, ...)

+ +

Returns the maximum value in a collection.

+ + +
+_.max {1,2,3} -- => 3
+_.max {'a','b','c'} -- => 'c'
+
+
+ + +

Can take an iterator function to extract a specific property.

+ + +
+local peoples = {
+  {name = 'John', age = 23},{name = 'Peter', age = 17},
+  {name = 'Steve', age = 15},{age = 33}}
+_.max(peoples,function(people) return people.age end) -- => 33
+
+
+ + +

min (t, transform, ...)

+ +

Returns the minimum value in a collection.

+ + +
+_.min {1,2,3} -- => 1
+_.min {'a','b','c'} -- => 'a'
+
+
+ + +

Can take an iterator function to extract a specific property.

+ + +
+local peoples = {
+  {name = 'John', age = 23},{name = 'Peter', age = 17},
+  {name = 'Steve', age = 15},{age = 33}}
+_.min(peoples,function(people) return people.age end) -- => 15
+
+
+ + +

shuffle (t, seed)

+ +

Shuffles a collection.

+ + +
+local list = _.shuffle {1,2,3,4,5,6} -- => "{3,2,6,4,1,5}"
+_.each(list,print)
+
+ + +

same (a, b)

+ +

Tests whether or not all values in each of the passed-in tables exists in both tables.

+ + +
+local a = {'a','b','c','d'}
+local b = {'b','a','d','c'}
+_.same(a,b) -- => true
+
+b[#b+1] = 'e'
+_.same(a,b) -- => false
+
+
+ + +

sort (t, comp)

+ +

Sorts a collection.

+ + +
+_.sort({'b','a','d','c'}) -- => "{'a','b','c','d'}"
+
+
+ + +

Handles custom comparison functions.

+ + +
+_.sort({'b','a','d','c'}, function(a,b)
+  return a:byte() > b:byte()
+end) -- => "{'d','c','b','a'}"
+
+
+ + +

groupBy (t, iter, ...)

+ +

Groups values in a collection depending on their return value when passed to a predicate test.

+ + +
+_.groupBy({0,1,2,3,4,5,6},function(i,value)
+  return value%2==0 and 'even' or 'odd'
+end) -- => "{odd = {1,3,5}, even = {0,2,4,6}}"
+
+_.groupBy({0,'a',true, false,nil,b,0.5},function(i,value)
+  return type(value)
+end) -- => "{number = {0,0.5}, string = {'a'}, boolean = {true, false}}"
+
+
+ + +

countBy (t, iter, ...)

+ +

Splits a table in subsets and provide the count for each subset.

+ + +
+_.countBy({0,1,2,3,4,5,6},function(i,value)
+  return value%2==0 and 'even' or 'odd'
+end) -- => "{odd = 3, even = 4}"
+
+
+ + +

size (...)

+ +

When given a table, provides the count for the very number of values in that table.

+ + +
+_.size {1,2,3} -- => 3
+_.size {one = 1, two = 2} -- => 2
+
+
+ + +

When given a vararg list of argument, returns the count of these arguments.

+ + +
+_.size(1,2,3) -- => 3
+_.size('a','b',{}, function() end) -- => 4
+
+
+ + +

containsKeys (t, other)

+ +

Checks whether a table has all the keys existing in another table.

+ + +
+_.contains({1,2,3,4},{1,2,3}) -- => true
+_.contains({1,2,'d','b'},{1,2,3,5}) -- => true
+_.contains({x = 1, y = 2, z = 3},{x = 1, y = 2}) -- => true
+
+
+ + +

sameKeys (tA, tB)

+ +

Checks whether both tables features the same keys:

+ + +
+_.sameKeys({1,2,3,4},{1,2,3}) -- => false
+_.sameKeys({1,2,'d','b'},{1,2,3,5}) -- => true
+_.sameKeys({x = 1, y = 2, z = 3},{x = 1, y = 2}) -- => false
+
+
+ + +

[⬆]

+ +

+

Array functions

+ +

toArray (...)

+ +

Converts a vararg list of arguments to an array.

+ + +
+_.toArray(1,2,8,'d','a',0) -- => "{1,2,8,'d','a',0}"
+
+
+ + +

find (array, value, from)

+ +

Looks for a value in a given array and returns the position of the first occurence.

+ + +
+_.find({{4},{3},{2},{1}},{3}) -- => 2
+
+
+ + +

It can also start the search at a specific position in the array:

+ + +
+-- search value 4 starting from index 3
+_.find({1,4,2,3,4,5},4,3) -- => 5
+
+
+ + +

reverse (array)

+ +

Reverses an array.

+ + +
+_.reverse({1,2,3,'d'}) -- => "{'d',3,2,1}"
+
+
+ + +

selectWhile (array, f, ...

+

*Aliases: _.takeWhile*.

+ +

Collects values as long as they pass a given test. Stops on the first non-passing test.

+ + +
+_.selectWhile({2,4,5,8}, function(i,v)
+  return v%2==0
+end) -- => "{2,4}"
+
+
+ + +

dropWhile (array, f, ...

+

*Aliases: _.rejectWhile*.

+ +

Removes values as long as they pass a given test. Stops on the first non-passing test.

+ + +
+_.dropWhile({2,4,5,8}, function(i,v)
+  return v%2==0
+end) -- => "{5,8}"
+
+
+ + +

sortedIndex (array, value, comp, sort)

+ +

Returns the index at which a value should be inserted to preserve order.

+ + +
+_.sortedIndex({1,2,3},4) -- => 4
+
+
+ + +

Can take a custom comparison functions.

+ + +
+local comp = function(a,b) return a<b end
+_.sortedIndex({-5,0,4,4},3,comp) -- => 3
+
+
+ + +

indexOf (array, value)

+ +

Returns the index of a value in an array.

+ + +
+_.indexOf({1,2,3},2) -- => 2
+
+
+ + +

lastIndexOf (array, value)

+ +

Returns the index of the last occurence of a given value in an array.

+ + +
+_.lastIndexOf({1,2,2,3},2) -- => 3
+
+
+ + +

addTop (array, ...)

+ +

Adds given values at the top of an array. The latter values bubbles at the top.

+ + +
+local array = {1}
+_.addTop(array,1,2,3,4) -- => "{4,3,2,1,1}"
+
+
+ + +

push (array, ...)

+ +

Adds given values at the end of an array.

+ + +
+local array = {1}
+_.push(array,1,2,3,4) -- => "{1,1,2,3,4}"
+
+
+ + +

pop (array, n)

+

*Aliases: _.shift*.

+ +

Removes and returns the first value in an array.

+ + +
+local array = {1,2,3}
+local pop = _.pop(array) -- => "pop = 1", "array = {2,3}"
+
+
+ + +

unshift (array, n)

+ +

Removes and returns the last value in an array.

+ + +
+local array = {1,2,3}
+local value = _.unshift(array) -- => "value = 3", "array = {1,2}"
+
+
+ + +

pull (array, ...)

+

*Aliases: _.remove*.

+ +

Removes all provided values from a given array.

+ + +
+_.pull({1,2,1,2,3,4,3},1,2,3) -- => "{4}"
+
+
+ + +

removeRange (array, start, finish)

+

*Aliases: _.rmRange, _.chop*.

+ +

Trims out all values index within a range.

+ + +
+local array = {1,2,3,4,5,6,7,8,9}
+_.removeRange(array, 3,8) -- => "{1,2,9}"
+
+
+ + +

chunk (array, f, ...)

+ +

Iterates over an array aggregating consecutive values in subsets tables, on the basis of the return +value of f(key,value,...). Consecutive elements which return the same value are aggregated together.

+ + +
+local t = {1,1,2,3,3,4}
+_.chunk(t, function(k,v) return v%2==0 end) -- => "{{1,1},{2},{3,3},{4}}"
+
+
+ + +

slice (array, start, finish)

+

*Aliases: _.sub*.

+ +

Slices and returns a part of an array.

+ + +
+local array = {1,2,3,4,5,6,7,8,9}
+_.slice(array, 3,6) -- => "{3,4,5,6}"
+
+
+ + +

first (array, n)

+

*Aliases: _.head, _.take*.

+ +

Returns the first N elements in an array.

+ + +
+local array = {1,2,3,4,5,6,7,8,9}
+_.first(array,3) -- => "{1,2,3}"
+
+
+ + +

initial (array, n)

+ +

Excludes the last N elements in an array.

+ + +
+local array = {1,2,3,4,5,6,7,8,9}
+_.initial(array,5) -- => "{1,2,3,4}"
+
+
+ + +

last (array, n)

+

*Aliases: _.skip*.

+ +

Returns the last N elements in an array.

+ + +
+local array = {1,2,3,4,5,6,7,8,9}
+_.last(array,3) -- => "{7,8,9}"
+
+
+ + +

rest (array, index)

+

*Aliases: _.tail*.

+ +

Trims out all values indexed before index.

+ + +
+local array = {1,2,3,4,5,6,7,8,9}
+_.rest(array,6) -- => "{6,7,8,9}"
+
+
+ + +

compact (array)

+ +

Trims out all falsy values.

+ + +
+_.compact {a,'aa',false,'bb',true} -- => "{'aa','bb',true}"
+
+
+ + +

flatten (array, shallow)

+ +

Flattens a nested array.

+ + +
+_.flatten({1,{2,3},{4,5,{6,7}}}) -- => "{1,2,3,4,5,6,7}"
+
+
+ + +

When given arg "shallow", flatten only at the first level.

+ + +
+_.flatten({1,{2},{{3}}},true) -- => "{1,{2},{{3}}}"
+
+
+ + +

difference (array, array2)

+

*Aliases: _.without, _.diff*.

+ +

Returns values in the given array not present in a second array.

+ + +
+local array = {1,2,'a',4,5}
+_.difference(array,{1,'a'}) -- => "{2,4,5}"
+
+
+ + +

union (...)

+ +

Produces a duplicate-free union of all passed-in arrays.

+ + +
+local A = {'a'}
+local B = {'a',1,2,3}
+local C = {2,10}
+_.union(A,B,C) -- => "{'a',1,2,3,10}"
+
+
+ + +

intersection (array, ...)

+ +

Returns the intersection (common-part) of all passed-in arrays:

+ + +
+local A = {'a'}
+local B = {'a',1,2,3}
+local C = {2,10,1,'a'}
+_.intersection(A,B,C) -- => "{'a',2,1}"
+
+
+ + +

symmetricDifference (array, array2)

+

*Aliases: _.symdiff,_.xor*.

+ +

Returns values in the first array not present in the second and also values in the second array not present in the first one.

+ + +
+local array = {1,2,3}
+local array2 = {1,4,5}
+_.symmetricDifference(array, array2) -- => "{2,3,4,5}"
+
+
+ + +

unique (array)

+

*Aliases: _.uniq*.

+ +

Makes an array duplicate-free.

+ + +
+_.unique {1,1,2,2,3,3,4,4,4,5} -- => "{1,2,3,4,5}"
+
+
+ + +

isunique (array)

+

*Aliases: _.isuniq*.

+ +

Checks if a given array contains no duplicate value.

+ + +
+_.isunique({1,2,3,4,5}) -- => true
+_.isunique({1,2,3,4,4}) -- => false
+
+
+ + +

zip (...)

+ +

Zips values from different arrays, on the basis on their common keys.

+ + +
+local names = {'Bob','Alice','James'}
+local ages = {22, 23}
+_.zip(names,ages) -- => "{{'Bob',22},{'Alice',23},{'James'}}"
+
+
+ + +

append (array, other)

+ +

Appends two arrays.

+ + +
+_.append({1,2,3},{'a','b'}) -- => "{1,2,3,'a','b'}"
+
+
+ + +

interleave (...)

+ +

Interleaves values from passed-in arrays.

+ + +
+t1 = {1, 2, 3}
+t2 = {'a', 'b', 'c'}
+_.interleave(t1, t2) -- => "{1,'a',2,'b',3,'c'}"
+
+
+ + +

interpose (value, array)

+ +

Interposes a value between consecutive values in an arrays.

+ + +
+_.interleave('a', {1,2,3}) -- => "{1,'a',2,'a',3}"
+
+
+ + +

range (...)

+ +

Generates an arithmetic sequence.

+ + +
+_.range(1,4) -- => "{1,2,3,4}"
+
+
+ + +

In case a single value is provided, it generates a sequence from 0 to that value.

+ + +
+_.range(3) -- => "{0,1,2,3}"
+
+
+ + +

The incremental step can also be provided as third argument.

+ + +
+_.range(0,2,0.7) -- => "{0,0.7,1.4}"
+
+
+ + +

rep (value, n)

+ +

Generates a list of n repetitions of a value.

+ + +
+_.rep(4,3) -- => "{4,4,4}"
+
+
+ + +

partition (array, n)

+

*Aliases: _.part*.

+ +

Returns an iterator function for partitions of a given array.

+ + +
+local t = {1,2,3,4,5,6}
+for p in _.partition(t,2) do
+  print(table.concat(p, ','))
+end
+
+-- => 1,2
+-- => 3,4
+-- => 5,6
+
+
+ + +

permutation (array)

+

*Aliases: _.perm*.

+ +

Returns an iterator function for permutations of a given array.

+ + +
+t = {'a','b','c'}
+for p in _.permutation(t) do
+  print(table.concat(p))
+end
+
+-- => 'bca'
+-- => 'cba'
+-- => 'cab'
+-- => 'acb'
+-- => 'bac'
+-- => 'abc'
+
+
+ + +

invert (array)

+

*Aliases: _.mirror*.

+ +

Switches key-value pairs:

+ + +
+_.invert {'a','b','c'} -- => "{a=1, b=2, c=3}"
+
+
+ + +

concat (array, sep, i, j)

+

*Aliases: _.join*.

+ +

Concatenates a given array values:

+ + +
+_.concat({'a',1,0,1,'b'}) -- => 'a101b'
+
+
+ + +

[⬆]

+ +

+

Utility functions

+ +

identity (value)

+ +

Returns the passed-in value.
+This function is internally used as a default transformation function.

+ + +
+_.identity(1)-- => 1
+_.identity(false) -- => false
+_.identity('hello!') -- => 'hello!'
+
+
+ + +

once (f)

+ +

Produces a function that runs only once. Successive calls to this function will still yield the same input.

+ + +
+local sq = _.once(function(a) return a*a end)
+sq(1) -- => 1
+sq(2) -- => 1
+sq(3) -- => 1
+sq(4) -- => 1
+sq(5) -- => 1
+
+
+ + +

memoize (f, hash)

+

*Aliases: _.cache*.

+ +

Memoizes a slow-running function. It caches the result for a specific input, so that the next time the function is called with the same input, it will lookup the result in its cache, instead of running again the function body.

+ + +
+local function fibonacci(n)
+  return n < 2 and n or fibonacci(n-1)+fibonacci(n-2)
+end
+local mem_fibonacci = _.memoize(fibonacci)
+fibonacci(20) -- => 6765 (but takes some time)
+mem_fibonacci(20) -- => 6765 (takes less time)
+
+
+ + +

after (f, count)

+ +

Produces a function that will respond only after a given number of calls.

+ + +
+local f = _.after(_.identity,3)
+f(1) -- => nil
+f(2) -- => nil
+f(3) -- => 3
+f(4) -- => 4
+
+
+ + +

compose (...)

+ +

Composes functions. Each function consumes the return value of the one that follows.

+ + +
+local function f(x) return x^2 end
+local function g(x) return x+1 end
+local function h(x) return x/2 end
+local compositae = _.compose(f,g,h)
+compositae(10) -- => 36
+compositae(20) -- => 121
+
+
+ + +

pipe (value, ...)

+ +

Pipes a value through a series of functions.

+ + +
+local function f(x) return x^2 end
+local function g(x) return x+1 end
+local function h(x) return x/2 end
+_.pipe(10,f,g,h) -- => 36
+_.pipe(20,f,g,h) -- => 121
+
+
+ + +

complement (f)

+ +

Returns a function which returns the logical complement of a given function.

+ + +
+_.complement(function() return true end)() -- => false
+
+
+ + +

juxtapose (value, ...)

+

*Aliases: _.juxt*.

+ +

Calls a sequence of functions with the same input.

+ + +
+local function f(x) return x^2 end
+local function g(x) return x+1 end
+local function h(x) return x/2 end
+_.juxtapose(10, f, g, h) -- => 100, 11, 5
+
+
+ + +

wrap (f, wrapper)

+ +

Wraps a function inside a wrapper. Allows the wrapper to execute code before and after function run.

+ + +
+local greet = function(name) return "hi: " .. name end
+local greet_backwards = _.wrap(greet, function(f,arg)
+  return f(arg) ..'\nhi: ' .. arg:reverse()
+end)
+greet_backwards('John')
+
+-- => hi: John
+-- => hi: nhoJ
+
+
+ + +

times (n, iter, ...)

+ +

Calls a given function n times.

+ + +
+local f = ('Lua programming'):gmatch('.')
+_.times(3,f) -- => {'L','u','a'}
+
+
+ + +

bind (f, v)

+ +

Binds a value to be the first argument to a function.

+ + +
+local sqrt2 = _.bind(math.sqrt,2)
+sqrt2() -- => 1.4142135623731
+
+
+ + +

bindn (f, ...)

+ +

Binds a variable number of values to be the first arguments to a function.

+ + +
+local function out(...) return table.concat {...} end
+local out = _.bindn(out,'OutPut',':',' ')
+out(1,2,3) -- => OutPut: 123
+out('a','b','c','d') -- => OutPut: abcd
+
+
+ + +

uniqueId (template, ...)

+

*Aliases: _.uid*.

+ +

Returns an unique integer ID.

+ + +
+_.uniqueId() -- => 1
+
+
+ + +

Can handle string templates for formatted output.

+ + +
+_.uniqueId('ID%s') -- => 'ID2'
+
+
+ + +

Or a function, for the same purpose.

+ + +
+local formatter = function(ID) return '$'..ID..'$' end
+_.uniqueId(formatter) -- => '$ID1$'
+
+
+ + +

[⬆]

+ +

+

Object functions

+ +

keys (obj)

+ +

Collects the names of an object attributes.

+ + +
+_.keys({1,2,3}) -- => "{1,2,3}"
+_.keys({x = 0, y = 1}) -- => "{'y','x'}"
+
+
+ + +

values (obj)

+ +

Collects the values of an object attributes.

+ + +
+_.values({1,2,3}) -- => "{1,2,3}"
+_.values({x = 0, y = 1}) -- => "{1,0}"
+
+
+ + +

toBoolean (value)

+ +

Converts a given value to a boolean.

+ + +
+_.toBoolean(true) -- => true
+_.toBoolean(false) -- => false
+_.toBoolean(nil) -- => false
+_.toBoolean({}) -- => true
+_.toBoolean(1) -- => true
+
+
+ + +

extend (destObj, ...)

+ +

Extends a destination object with the properties of some source objects.

+ + +
+_.extend({},{a = 'b', c = 'd'}) -- => "{a = 'b', c = 'd'}"
+
+
+ + +

functions (obj, recurseMt)

+

*Aliases: _.methods*.

+ +

Returns all functions names within an object.

+ + +
+_.functions(coroutine) -- => "{'create','resume','running','status','wrap','yield'}"
+
+
+ + +

clone (obj, shallow)

+ +

Clones a given object.

+ + +
+local obj = {1,2,3}
+local obj2 = _.clone(obj)
+print(obj2 == obj) -- => false
+print(_.isEqual(obj2, obj)) -- => true
+
+
+ + +

tap (obj, f, ...)

+ +

Invokes a given interceptor function on some object, and then returns the object itself. Useful to tap into method chaining to hook intermediate results. +The pased-interceptor is prototyped as f(obj,...).

+ + +
+local v = _.chain({1,2,3,4,5,6,7,8,9,10)
+  :filter(function(k,v) return v%2~=0 end) -- filters even values
+  :tap(function(v) print('Max is', _.max(v) end) -- Tap max values
+  :map(function(k,v) return k^2)
+  :value() -- =>    Max is 9
+
+
+ + +

has (obj, key)

+ +

Checks if an object has a given attribute.

+ + +
+_.has(_,'has') -- => true
+_.has(coroutine,'resume') -- => true
+_.has(math,'random') -- => true
+
+
+ + +

pick (obj, ...)

+

*Aliases: _.choose*.

+ +

Collects whilelisted properties of a given object.

+ + +
+local object = {a = 1, b = 2, c = 3}
+_.pick(object,'a','c') -- => "{a = 1, c = 3}"
+
+
+ + +

omit (obj, ...)

+

*Aliases: _.drop*.

+ +

Omits blacklisted properties of a given object.

+ + +
+local object = {a = 1, b = 2, c = 3}
+_.omit(object,'a','c') -- => "{b = 2}"
+
+
+ + +

template (obj, template)

+

*Aliases: _.defaults*.

+ +

Applies a template on an object, preserving existing properties.

+ + +
+local obj = {a = 0}
+_.template(obj,{a = 1, b = 2, c = 3}) -- => "{a=0, c=3, b=2}"
+
+
+ + +

isEqual (objA, objB, useMt)

+

*Aliases: _.compare*.

+ +

Compares objects:

+ + +
+_.isEqual(1,1) -- => true
+_.isEqual(true,false) -- => false
+_.isEqual(3.14,math.pi) -- => false
+_.isEqual({3,4,5},{3,4,{5}}) -- => false
+
+
+ + +

result (obj, method, ...)

+ +

Calls an object method, passing it as a first argument the object itself.

+ + +
+_.result('abc','len') -- => 3
+_.result({'a','b','c'},table.concat) -- => 'abc'
+
+
+ + +

isTable (t)

+ +

Is the given argument an object (i.e a table) ?

+ + +
+_.isTable({}) -- => true
+_.isTable(math) -- => true
+_.isTable(string) -- => true
+
+
+ + +

isCallable (obj)

+ +

Is the given argument callable ?

+ + +
+_.isCallable(print) -- => true
+_.isCallable(function() end) -- => true
+_.isCallable(setmetatable({},{__index = string}).upper) -- => true
+_.isCallable(setmetatable({},{__call = function() return end})) -- => true
+
+
+ + +

isArray (obj)

+ +

Is the given argument an array (i.e. a sequence) ?

+ + +
+_.isArray({}) -- => true
+_.isArray({1,2,3}) -- => true
+_.isArray({'a','b','c'}) -- => true
+
+
+ + +

isIterable (obj)

+ +

Checks if the given object is iterable with pairs .

+ + +
+_.isIterable({}) -- => true
+_.isIterable(function() end) -- => false
+_.isIterable(false) -- => false
+_.isIterable(1) -- => false
+
+
+ + +

isEmpty (obj)

+ +

Is the given argument empty ?

+ + +
+_.isEmpty('') -- => true
+_.isEmpty({})  -- => true
+_.isEmpty({'a','b','c'}) -- => false
+
+
+ + +

isString (obj)

+ +

Is the given argument a string ?

+ + +
+_.isString('') -- => true
+_.isString('Hello') -- => false
+_.isString({}) -- => false
+
+
+ + +

isFunction (obj)

+ +

Is the given argument a function ?

+ + +
+_.isFunction(print) -- => true
+_.isFunction(function() end) -- => true
+_.isFunction({}) -- => false
+
+
+ + +

isNil (obj)

+ +

Is the given argument nil ?

+ + +
+_.isNil(nil) -- => true
+_.isNil() -- => true
+_.isNil({}) -- => false
+
+
+ + +

isNumber (obj)

+ +

Is the given argument a number ?

+ + +
+_.isNumber(math.pi) -- => true
+_.isNumber(math.huge) -- => true
+_.isNumber(0/0) -- => true
+_.isNumber() -- => false
+
+
+ + +

isNaN (obj)

+ +

Is the given argument NaN ?

+ + +
+_.isNaN(1) -- => false
+_.isNaN(0/0) -- => true
+
+
+ + +

isFinite (obj)

+ +

Is the given argument a finite number ?

+ + +
+_.isFinite(99e99) -- => true
+_.isFinite(math.pi) -- => true
+_.isFinite(math.huge) -- => false
+_.isFinite(1/0) -- => false
+_.isFinite(0/0) -- => false
+
+
+ + +

isBoolean (obj)

+ +

Is the given argument a boolean ?

+ + +
+_.isBoolean(true) -- => true
+_.isBoolean(false) -- => true
+_.isBoolean(1==1) -- => true
+_.isBoolean(print) -- => false
+
+
+ + +

isInteger (obj)

+ +

Is the given argument an integer ?

+ + +
+_.isInteger(math.pi) -- => false
+_.isInteger(1) -- => true
+_.isInteger(-1) -- => true
+
+
+ + +

[⬆]

+ +

+

Chaining

+ +

Method chaining (also known as name parameter idiom), is a technique for invoking consecutively method calls in object-oriented style. +Each method returns an object, and methods calls are chained together. +Moses offers chaining for your perusal.
+Let's use chaining to get the count of evey single word in some lyrics (case won't matter here).

+ + + +
+local lyrics = {
+  "I am a lumberjack and I am okay",
+  "I sleep all night and I work all day",
+  "He is a lumberjack and he is okay",
+  "He sleeps all night and he works all day"
+}
+
+local stats = _.chain(lyrics)
+  :map(function(k,line)
+    local t = {}
+    for w in line:gmatch('(%w+)') do
+      t[#t+1] = w
+    end
+    return t
+  end)
+  :flatten()
+  :countBy(function(i,v) return v:lower() end)
+  :value()
+
+-- => "{
+-- =>    sleep = 1, night = 2, works = 1, am = 2, is = 2,
+-- =>    he = 2, and = 4, I = 4, he = 2, day = 2, a = 2,
+-- =>    work = 1, all = 4, okay = 2
+-- =>  }"
+
+
+ + +

For convenience, you can also use _(value) to start chaining methods, instead of _.chain(value).

+ +

Note that one can use :value() to unwrap a chained object.

+ + +
+local t = {1,2,3}
+print(_(t):value() == t) -- => true
+
+
+ + +

[⬆]

+ +

+

Import

+ +

All library functions can be imported in a context using import into a specified context.

+ + +
+local context = {}
+_.import(context)
+
+context.each({1,2,3},print)
+
+-- => 1 1
+-- => 2 2
+-- => 3 3
+
+
+ + +

When no context was provided, it defaults to the global environment _G.

+ + +
+_.import()
+
+each({1,2,3},print)
+
+-- => 1 1
+-- => 2 2
+-- => 3 3
+
+
+ + +

Passing noConflict argument leaves untouched conflicting keys while importing into the context.

+ + +
+local context = {each = 1}
+_.import(context, true)
+
+print(context.each) -- => 1
+context.eachi({1,2,3},print)
+
+-- => 1 1
+-- => 2 2
+-- => 3 3
+
+
+ + +

[⬆] + +

+
+
+generated by LDoc 1.4.0 +
+
+ + diff --git a/files/docs/moses/tutorial.md b/files/docs/moses/tutorial.md new file mode 100644 index 0000000..6b39f13 --- /dev/null +++ b/files/docs/moses/tutorial.md @@ -0,0 +1,1466 @@ +*Moses: a utility-belt library for Lua* + +__Moses__ is a Lua utility library which provides support for functional programming. +It complements built-in Lua functions, making easier common operations on tables, arrays, lists, collections, objects, and a lot more.
+__Moses__ was deeply inspired by [Underscore.js](http://documentcloud.github.com/underscore/). + +# Table of Contents + +* [Adding *Moses* to your project](#adding) +* [*Moses*' API](#API) + * [Table functions](#table) + * [Array functions](#array) + * [Utility functions](#utility) + * [Object functions](#object) + * [Chaining](#chaining) + * [Import](#import) + +# Adding *Moses* to your project + +Drop the file [moses.lua](http://github.com/Yonaba/Moses/blob/master/moses.lua) into your project and add it to your code with the *require* function: + +```lua +local _ = require ("moses") +```` + +*Note: Lua purists tend to use "\_" to design a "dummy variable". Here, the usage of this underscore is quite idiomatic and refers to the name [Underscore](http://documentcloud.github.com/underscore/), the JS library from which *Moses* takes inspiration*. + +**[[⬆]](#TOC)** + +# *Moses*' API + +*Moses*' consists of a large set of functions that can be classified into four categories: + +* __Table functions__, which are mostly meant for tables, i.e Lua tables which contains both an array-part and/or a map-part, +* __Array functions__, meant for array lists (or sequences), +* __Utility functions__, +* __Object functions__, meant for instances/classes. + +**[[⬆]](#TOC)** + +## Table functions + + +### each (t, f, ...) +*Aliases: `_.forEach`*. + +Iterates over each key-value pair in table. + +```lua +_.each({1,2,3},print) + +-- => 1 1 +-- => 2 2 +-- => 3 3 +```` + +The table can be map-like (array part and hash-part). + +```lua +_.each({one = 1, two = 2, three = 3},print) + +-- => one 1 +-- => two 2 +-- => three 3 +```` + +Can index and assign in an outer table or in the passed-in table: + +```lua +t = {'a','b','c'} +_.each(t,function(i,v) + t[i] = v:rep(2) + print(t[i]) +end) + +-- => 1 aa +-- => 2 bb +-- => 3 cc +```` + +### eachi (t, f, ...) +*Aliases: `_.forEachi`*. + +Iterates only on integer keys in a sparse array table. + +```lua +_.eachi({1,2,3},print) + +-- => 1 1 +-- => 2 2 +-- => 3 3 +```` + +The given array can be sparse, or even have a hash-like part. + +```lua +local t = {a = 1, b = 2, [0] = 1, [-1] = 6, 3, x = 4, 5} +_.eachi(t,function(i,v) + print(i,v) +end) + +-- => -1 6 +-- => 0 1 +-- => 1 3 +-- => 2 5 +```` + +### at (t, ...) + +Collects all values at some specific keys and returns them in an array. + +```lua +local t = {4,5,6} +_.at(t,1,3) -- => "{4,6}" + +local t = {a = 4, bb = true, ccc = false} +_.at(t,'a', 'ccc') -- => "{4, false}" +```` + +### count (t, value) + +Counts the number of occurences of a given value in a table. + +```lua +_.count({1,1,2,3,3,3,2,4,3,2},1) -- => 2 +_.count({1,1,2,3,3,3,2,4,3,2},2) -- => 2 +_.count({1,1,2,3,3,3,2,4,3,2},3) -- => 4 +_.count({false, false, true},false) -- => 2 +_.count({false, false, true},true) -- => 1 +```` + +Returns the size of the list in case no value was provided. + +```lua +_.count({1,1,2,3,3}) -- => 5 +```` + +### countf (t, f, ...) + +Count the number of occurences of all values passing an iterator test. + +```lua +_.countf({1,2,3,4,5,6}, function(i,v) + return v%2==0 +end) -- => 3 + +_.countf({print, pairs, os, assert, ipairs}, function(i,v) + return type(v)=='function' +end) -- => 4 +```` + +### cycle (t, n) +*Aliases: `_.loop`*. + +Returns a function which iterates on each key-value pair in a given table (similarly to `_.each`), except that it restarts iterating again `n` times. +If `n` is not provided, it defaults to 1. + +```lua +local t = {'a,'b','c'} +for k,v in _.cycle(t, 2) do + print(k,v) +end + +-- => 1 'a' +-- => 2 'b' +-- => 3 'c' +-- => 1 'a' +-- => 2 'b' +-- => 3 'c' +```` + +Supports array-like tables and map-like tables. + +```lua +local t = {x = 1, y = 2, z = 3} +for k,v in _.cycle(t) do + print(k,v) +end + +-- => y 2 +-- => x 1 +-- => z 3 +```` + +### map (t, f, ...) +*Aliases: `_.collect`*. + +Executes a function on each key-value pairs. + +```lua +_.map({1,2,3},function(i,v) + return v+10 +end)) -- => "{11,12,13}" +```` + +```lua +_.map({a = 1, b = 2},function(k,v) + return k..v +end) -- => "{a = 'a1', b = 'b2'}" +```` + +### reduce (t, f, state) +*Aliases: `_.inject`, `_.foldl`*. + +Can sums all values in a table. + +```lua +_.reduce({1,2,3,4},function(memo,v) + return memo+v +end) -- => 10 +```` + +Or concatenates all values. + +```lua +_.reduce({'a','b','c','d'},function(memo,v) + return memo..v +end) -- => abcd +```` + +### reduceRight (t, f, state) +*Aliases: `_.injectr`, `_.foldr`*. + +Similar to `_.reduce`, but performs from right to left. + +```lua +local initial_state = 256 +_.reduceRight({1,2,4,16},function(memo,v) + return memo/v +end,initial_state) -- => 2 +```` + +### mapReduce (t, f, state) +*Aliases: `_.mapr`*. + +Reduces while saving intermediate states. + +```lua +_.mapReduce({'a','b','c'},function(memo,v) + return memo..v +end) -- => "{'a', 'ab', 'abc'}" +```` + +### mapReduceRight (t, f, state) +*Aliases: `_.maprr`*. + +Reduces from right to left, while saving intermediate states. + +```lua +_.mapReduceRight({'a','b','c'},function(memo,v) + return memo..v +end) -- => "{'c', 'cb', 'cba'}" +```` + +### include (t, value) +*Aliases: `_.any`, `_.some`*. + +Looks for a value in a table. + +```lua +_.include({6,8,10,16,29},16) -- => true +_.include({6,8,10,16,29},1) -- => false + +local complex_table = {18,{2,{3}}} +local collection = {6,{18,{2,6}},10,{18,{2,{3}}},29} +_.include(collection, complex_table) -- => true +```` + +Handles iterator functions. + +```lua +local function isUpper(v) return v:upper()== v end +_.include({'a','B','c'},isUpper) -- => true +```` + +### detect (t, value) + +Returns the index of a value in a table. + +```lua +_.detect({6,8,10,16},8) -- => 2 +_.detect({nil,true,0,true,true},false) -- => nil + +local complex_table = {18,{2,6}} +local collection = {6,{18,{2,6}},10,{18,{2,{3}}},29} +_.detect(collection, complex_table) -- => 2 +```` + +Handles iterator functions. + +```lua +local function isUpper(v) + return v:upper()==v +end +_.detect({'a','B','c'},isUpper) -- => 2 +```` + +### contains (t, value) + +Returns true if the passed-in value was found in a given table. + +```lua +_.contains({6,8,10,16},8) -- => true +_.contains({nil,true,0,true,true},false) -- => false +```` + +It can lookup for objects, and accepts iterator functions aswell: + +```lua +_.contains({6,{18,{2,6}},10,{18,{2,{3}}},29},{18,{2,6}}) -- => true + +_.contains({'a','B','c'}, function(array_value) + return (array_value:upper() == array_value) +end) -- => true +```` + +### findWhere (t, props) + +Looks through a table and returns the first value that matches all of the key-value pairs listed in properties. + +```lua +local a = {a = 1, b = 2, c = 3} +local b = {a = 2, b = 3, d = 4} +local c = {a = 3, b = 4, e = 5} +_.findWhere({a, b, c}, {a = 3, b = 4}) == c -- => true +```` + +### select (t, f, ...) +*Aliases: `_.filte`*. + +Collects values passing a validation test. + +```lua +-- Even values +_.select({1,2,3,4,5,6,7}, function(key,value) + return (value%2==0) +end) -- => "{2,4,6}" + +-- Odd values +_.select({1,2,3,4,5,6,7}, function(key,value) + return (value%2~=0) +end) -- => "{1,3,5,7}" +```` + +### reject (t, f, ...) +*Aliases: `_.reject`*. + +Removes all values failing a validation test: + +```lua +_.reject({1,2,3,4,5,6,7}, function(key,value) + return (value%2==0) +end) -- => "{1,3,5,7}" + +_.reject({1,2,3,4,5,6,7}, function(key,value) + return (value%2~=0) +end) -- => "{2,4,6}" +```` + +### all (t, f, ...) +*Aliases: `_.every`*. + +Checks whether or not all elements pass a validation test. + +```lua +_.all({2,4,6}, function(key,value) + return (value%2==0) +end) -- => true +```` + +### invoke (t, method, ...) + +Invokes a given function on each value in a table + +```lua +_.invoke({'a','bea','cdhza'},string.len) -- => "{1,3,5}" +```` + +Can reference the method of the same name in each value. + +```lua +local a = {} +function a:call() return 'a' end +local b, c, d = {}, {}, {} +b.call, c.call, d.call = a.call, a.call, a.call + +_.invoke({a,b,c,d},'call') -- => "{'a','a','a','a'}" +```` + +### pluck (t, property) + +Fetches all values indxed with specific key in a table of objects. + +```lua +local peoples = { + {name = 'John', age = 23},{name = 'Peter', age = 17}, + {name = 'Steve', age = 15},{age = 33}} + +_.pluck(peoples,'age') -- => "{23,17,15,33}" +_.pluck(peoples,'name') -- => "{'John', 'Peter', 'Steve'}" +```` + +### max (t, transform, ...) + +Returns the maximum value in a collection. + +```lua +_.max {1,2,3} -- => 3 +_.max {'a','b','c'} -- => 'c' +```` + +Can take an iterator function to extract a specific property. + +```lua +local peoples = { + {name = 'John', age = 23},{name = 'Peter', age = 17}, + {name = 'Steve', age = 15},{age = 33}} +_.max(peoples,function(people) return people.age end) -- => 33 +```` + +### min (t, transform, ...) + +Returns the minimum value in a collection. + +```lua +_.min {1,2,3} -- => 1 +_.min {'a','b','c'} -- => 'a' +```` + +Can take an iterator function to extract a specific property. + +```lua +local peoples = { + {name = 'John', age = 23},{name = 'Peter', age = 17}, + {name = 'Steve', age = 15},{age = 33}} +_.min(peoples,function(people) return people.age end) -- => 15 +```` + +### shuffle (t, seed) + +Shuffles a collection. + +```lua +local list = _.shuffle {1,2,3,4,5,6} -- => "{3,2,6,4,1,5}" +_.each(list,print) +```` + +### same (a, b) + +Tests whether or not all values in each of the passed-in tables exists in both tables. + +```lua +local a = {'a','b','c','d'} +local b = {'b','a','d','c'} +_.same(a,b) -- => true + +b[#b+1] = 'e' +_.same(a,b) -- => false +```` + +### sort (t, comp) + +Sorts a collection. + +```lua +_.sort({'b','a','d','c'}) -- => "{'a','b','c','d'}" +```` + +Handles custom comparison functions. + +```lua +_.sort({'b','a','d','c'}, function(a,b) + return a:byte() > b:byte() +end) -- => "{'d','c','b','a'}" +```` + +### groupBy (t, iter, ...) + +Groups values in a collection depending on their return value when passed to a predicate test. + +```lua +_.groupBy({0,1,2,3,4,5,6},function(i,value) + return value%2==0 and 'even' or 'odd' +end) -- => "{odd = {1,3,5}, even = {0,2,4,6}}" + +_.groupBy({0,'a',true, false,nil,b,0.5},function(i,value) + return type(value) +end) -- => "{number = {0,0.5}, string = {'a'}, boolean = {true, false}}" +```` + +### countBy (t, iter, ...) + +Splits a table in subsets and provide the count for each subset. + +```lua +_.countBy({0,1,2,3,4,5,6},function(i,value) + return value%2==0 and 'even' or 'odd' +end) -- => "{odd = 3, even = 4}" +```` + +### size (...) + +When given a table, provides the count for the very number of values in that table. + +```lua +_.size {1,2,3} -- => 3 +_.size {one = 1, two = 2} -- => 2 +```` + +When given a vararg list of argument, returns the count of these arguments. + +```lua +_.size(1,2,3) -- => 3 +_.size('a','b',{}, function() end) -- => 4 +```` + +### containsKeys (t, other) + +Checks whether a table has all the keys existing in another table. + +```lua +_.contains({1,2,3,4},{1,2,3}) -- => true +_.contains({1,2,'d','b'},{1,2,3,5}) -- => true +_.contains({x = 1, y = 2, z = 3},{x = 1, y = 2}) -- => true +```` + +### sameKeys (tA, tB) + +Checks whether both tables features the same keys: + +```lua +_.sameKeys({1,2,3,4},{1,2,3}) -- => false +_.sameKeys({1,2,'d','b'},{1,2,3,5}) -- => true +_.sameKeys({x = 1, y = 2, z = 3},{x = 1, y = 2}) -- => false +```` + +**[[⬆]](#TOC)** + +## Array functions + +### toArray (...) + +Converts a vararg list of arguments to an array. + +```lua +_.toArray(1,2,8,'d','a',0) -- => "{1,2,8,'d','a',0}" +```` + +### find (array, value, from) + +Looks for a value in a given array and returns the position of the first occurence. + +```lua +_.find({{4},{3},{2},{1}},{3}) -- => 2 +```` + +It can also start the search at a specific position in the array: + +```lua +-- search value 4 starting from index 3 +_.find({1,4,2,3,4,5},4,3) -- => 5 +```` + +### reverse (array) + +Reverses an array. + +```lua +_.reverse({1,2,3,'d'}) -- => "{'d',3,2,1}" +```` + +### selectWhile (array, f, ... +*Aliases: `_.takeWhile`*. + +Collects values as long as they pass a given test. Stops on the first non-passing test. + +```lua +_.selectWhile({2,4,5,8}, function(i,v) + return v%2==0 +end) -- => "{2,4}" +```` + +### dropWhile (array, f, ... +*Aliases: `_.rejectWhile`*. + +Removes values as long as they pass a given test. Stops on the first non-passing test. + +```lua +_.dropWhile({2,4,5,8}, function(i,v) + return v%2==0 +end) -- => "{5,8}" +```` + +### sortedIndex (array, value, comp, sort) + +Returns the index at which a value should be inserted to preserve order. + +```lua +_.sortedIndex({1,2,3},4) -- => 4 +```` + +Can take a custom comparison functions. + +```lua +local comp = function(a,b) return a 3 +```` + +### indexOf (array, value) + +Returns the index of a value in an array. + +```lua +_.indexOf({1,2,3},2) -- => 2 +```` + +### lastIndexOf (array, value) + +Returns the index of the last occurence of a given value in an array. + +```lua +_.lastIndexOf({1,2,2,3},2) -- => 3 +```` + +### addTop (array, ...) + +Adds given values at the top of an array. The latter values bubbles at the top. + +```lua +local array = {1} +_.addTop(array,1,2,3,4) -- => "{4,3,2,1,1}" +```` + +### push (array, ...) + +Adds given values at the end of an array. + +```lua +local array = {1} +_.push(array,1,2,3,4) -- => "{1,1,2,3,4}" +```` + +### pop (array, n) +*Aliases: `_.shift`*. + +Removes and returns the first value in an array. + +```lua +local array = {1,2,3} +local pop = _.pop(array) -- => "pop = 1", "array = {2,3}" +```` + +### unshift (array, n) + +Removes and returns the last value in an array. + +```lua +local array = {1,2,3} +local value = _.unshift(array) -- => "value = 3", "array = {1,2}" +```` + +### pull (array, ...) +*Aliases: `_.remove`*. + +Removes all provided values from a given array. + +```lua +_.pull({1,2,1,2,3,4,3},1,2,3) -- => "{4}" +```` + +### removeRange (array, start, finish) +*Aliases: `_.rmRange`, `_.chop`*. + +Trims out all values index within a range. + +```lua +local array = {1,2,3,4,5,6,7,8,9} +_.removeRange(array, 3,8) -- => "{1,2,9}" +```` + +### chunk (array, f, ...) + +Iterates over an array aggregating consecutive values in subsets tables, on the basis of the return +value of `f(key,value,...)`. Consecutive elements which return the same value are aggregated together. + +```lua +local t = {1,1,2,3,3,4} +_.chunk(t, function(k,v) return v%2==0 end) -- => "{{1,1},{2},{3,3},{4}}" +```` + +### slice (array, start, finish) +*Aliases: `_.sub`*. + +Slices and returns a part of an array. + +```lua +local array = {1,2,3,4,5,6,7,8,9} +_.slice(array, 3,6) -- => "{3,4,5,6}" +```` + +### first (array, n) +*Aliases: `_.head`, `_.take`*. + +Returns the first N elements in an array. + +```lua +local array = {1,2,3,4,5,6,7,8,9} +_.first(array,3) -- => "{1,2,3}" +```` + +### initial (array, n) + +Excludes the last N elements in an array. + +```lua +local array = {1,2,3,4,5,6,7,8,9} +_.initial(array,5) -- => "{1,2,3,4}" +```` + +### last (array, n) +*Aliases: `_.skip`*. + +Returns the last N elements in an array. + +```lua +local array = {1,2,3,4,5,6,7,8,9} +_.last(array,3) -- => "{7,8,9}" +```` + +### rest (array, index) +*Aliases: `_.tail`*. + +Trims out all values indexed before *index*. + +```lua +local array = {1,2,3,4,5,6,7,8,9} +_.rest(array,6) -- => "{6,7,8,9}" +```` + +### compact (array) + +Trims out all falsy values. + +```lua +_.compact {a,'aa',false,'bb',true} -- => "{'aa','bb',true}" +```` + +### flatten (array, shallow) + +Flattens a nested array. + +```lua +_.flatten({1,{2,3},{4,5,{6,7}}}) -- => "{1,2,3,4,5,6,7}" +```` + +When given arg "shallow", flatten only at the first level. + +```lua +_.flatten({1,{2},{{3}}},true) -- => "{1,{2},{{3}}}" +```` + +### difference (array, array2) +*Aliases: `_.without`, `_.diff`*. + +Returns values in the given array not present in a second array. + +```lua +local array = {1,2,'a',4,5} +_.difference(array,{1,'a'}) -- => "{2,4,5}" +```` + +### union (...) + +Produces a duplicate-free union of all passed-in arrays. + +```lua +local A = {'a'} +local B = {'a',1,2,3} +local C = {2,10} +_.union(A,B,C) -- => "{'a',1,2,3,10}" +```` + +### intersection (array, ...) + +Returns the intersection (common-part) of all passed-in arrays: + +```lua +local A = {'a'} +local B = {'a',1,2,3} +local C = {2,10,1,'a'} +_.intersection(A,B,C) -- => "{'a',2,1}" +```` + +### symmetricDifference (array, array2) +*Aliases: `_.symdiff`,`_.xor`*. + +Returns values in the first array not present in the second and also values in the second array not present in the first one. + +```lua +local array = {1,2,3} +local array2 = {1,4,5} +_.symmetricDifference(array, array2) -- => "{2,3,4,5}" +```` + +### unique (array) +*Aliases: `_.uniq`*. + +Makes an array duplicate-free. + +```lua +_.unique {1,1,2,2,3,3,4,4,4,5} -- => "{1,2,3,4,5}" +```` + +### isunique (array) +*Aliases: `_.isuniq`*. + +Checks if a given array contains no duplicate value. + +```lua +_.isunique({1,2,3,4,5}) -- => true +_.isunique({1,2,3,4,4}) -- => false +```` + +### zip (...) + +Zips values from different arrays, on the basis on their common keys. + +```lua +local names = {'Bob','Alice','James'} +local ages = {22, 23} +_.zip(names,ages) -- => "{{'Bob',22},{'Alice',23},{'James'}}" +```` + +### append (array, other) + +Appends two arrays. + +```lua +_.append({1,2,3},{'a','b'}) -- => "{1,2,3,'a','b'}" +```` + +### interleave (...) + +Interleaves values from passed-in arrays. + +```lua +t1 = {1, 2, 3} +t2 = {'a', 'b', 'c'} +_.interleave(t1, t2) -- => "{1,'a',2,'b',3,'c'}" +```` + +### interpose (value, array) + +Interposes a value between consecutive values in an arrays. + +```lua +_.interleave('a', {1,2,3}) -- => "{1,'a',2,'a',3}" +```` + +### range (...) + +Generates an arithmetic sequence. + +```lua +_.range(1,4) -- => "{1,2,3,4}" +```` + +In case a single value is provided, it generates a sequence from 0 to that value. + +```` +_.range(3) -- => "{0,1,2,3}" +```` + +The incremental step can also be provided as third argument. + +```lua +_.range(0,2,0.7) -- => "{0,0.7,1.4}" +```` + +### rep (value, n) + +Generates a list of n repetitions of a value. + +```lua +_.rep(4,3) -- => "{4,4,4}" +```` + +### partition (array, n) +*Aliases: `_.part`*. + +Returns an iterator function for partitions of a given array. + +```lua +local t = {1,2,3,4,5,6} +for p in _.partition(t,2) do + print(table.concat(p, ',')) +end + +-- => 1,2 +-- => 3,4 +-- => 5,6 +```` + +### permutation (array) +*Aliases: `_.perm`*. + +Returns an iterator function for permutations of a given array. + +```lua +t = {'a','b','c'} +for p in _.permutation(t) do + print(table.concat(p)) +end + +-- => 'bca' +-- => 'cba' +-- => 'cab' +-- => 'acb' +-- => 'bac' +-- => 'abc' +```` + +### invert (array) +*Aliases: `_.mirror`*. + +Switches key-value pairs: + +```lua +_.invert {'a','b','c'} -- => "{a=1, b=2, c=3}" +```` + +### concat (array, sep, i, j) +*Aliases: `_.join`*. + +Concatenates a given array values: + +```lua +_.concat({'a',1,0,1,'b'}) -- => 'a101b' +```` + +**[[⬆]](#TOC)** + +## Utility functions + +### identity (value) + +Returns the passed-in value.
+This function is internally used as a default transformation function. + +```lua +_.identity(1)-- => 1 +_.identity(false) -- => false +_.identity('hello!') -- => 'hello!' +```` + +### once (f) + +Produces a function that runs only once. Successive calls to this function will still yield the same input. + +```lua +local sq = _.once(function(a) return a*a end) +sq(1) -- => 1 +sq(2) -- => 1 +sq(3) -- => 1 +sq(4) -- => 1 +sq(5) -- => 1 +```` + +### memoize (f, hash) +*Aliases: `_.cache`*. + +Memoizes a slow-running function. It caches the result for a specific input, so that the next time the function is called with the same input, it will lookup the result in its cache, instead of running again the function body. + +```lua +local function fibonacci(n) + return n < 2 and n or fibonacci(n-1)+fibonacci(n-2) +end +local mem_fibonacci = _.memoize(fibonacci) +fibonacci(20) -- => 6765 (but takes some time) +mem_fibonacci(20) -- => 6765 (takes less time) +```` + +### after (f, count) + +Produces a function that will respond only after a given number of calls. + +```lua +local f = _.after(_.identity,3) +f(1) -- => nil +f(2) -- => nil +f(3) -- => 3 +f(4) -- => 4 +```` + +### compose (...) + +Composes functions. Each function consumes the return value of the one that follows. + +```lua +local function f(x) return x^2 end +local function g(x) return x+1 end +local function h(x) return x/2 end +local compositae = _.compose(f,g,h) +compositae(10) -- => 36 +compositae(20) -- => 121 +```` + +### pipe (value, ...) + +Pipes a value through a series of functions. + +```lua +local function f(x) return x^2 end +local function g(x) return x+1 end +local function h(x) return x/2 end +_.pipe(10,f,g,h) -- => 36 +_.pipe(20,f,g,h) -- => 121 +```` + +### complement (f) + +Returns a function which returns the logical complement of a given function. + +```lua +_.complement(function() return true end)() -- => false +```` + +### juxtapose (value, ...) +*Aliases: `_.juxt`*. + +Calls a sequence of functions with the same input. + +```lua +local function f(x) return x^2 end +local function g(x) return x+1 end +local function h(x) return x/2 end +_.juxtapose(10, f, g, h) -- => 100, 11, 5 +```` + +### wrap (f, wrapper) + +Wraps a function inside a wrapper. Allows the wrapper to execute code before and after function run. + +```lua +local greet = function(name) return "hi: " .. name end +local greet_backwards = _.wrap(greet, function(f,arg) + return f(arg) ..'\nhi: ' .. arg:reverse() +end) +greet_backwards('John') + +-- => hi: John +-- => hi: nhoJ +```` + +### times (n, iter, ...) + +Calls a given function `n` times. + +```lua +local f = ('Lua programming'):gmatch('.') +_.times(3,f) -- => {'L','u','a'} +```` + +### bind (f, v) + +Binds a value to be the first argument to a function. + +```lua +local sqrt2 = _.bind(math.sqrt,2) +sqrt2() -- => 1.4142135623731 +```` + +### bindn (f, ...) + +Binds a variable number of values to be the first arguments to a function. + +```lua +local function out(...) return table.concat {...} end +local out = _.bindn(out,'OutPut',':',' ') +out(1,2,3) -- => OutPut: 123 +out('a','b','c','d') -- => OutPut: abcd +```` + +### uniqueId (template, ...) +*Aliases: `_.uid`*. + +Returns an unique integer ID. + +```lua +_.uniqueId() -- => 1 +```` + +Can handle string templates for formatted output. + +```lua +_.uniqueId('ID%s') -- => 'ID2' +```` + +Or a function, for the same purpose. + +```lua +local formatter = function(ID) return '$'..ID..'$' end +_.uniqueId(formatter) -- => '$ID1$' +```` + +**[[⬆]](#TOC)** + +## Object functions + +### keys (obj) + +Collects the names of an object attributes. + +```lua +_.keys({1,2,3}) -- => "{1,2,3}" +_.keys({x = 0, y = 1}) -- => "{'y','x'}" +```` + +### values (obj) + +Collects the values of an object attributes. + +```lua +_.values({1,2,3}) -- => "{1,2,3}" +_.values({x = 0, y = 1}) -- => "{1,0}" +```` + +### toBoolean (value) + +Converts a given value to a boolean. + +```lua +_.toBoolean(true) -- => true +_.toBoolean(false) -- => false +_.toBoolean(nil) -- => false +_.toBoolean({}) -- => true +_.toBoolean(1) -- => true +```` + +### extend (destObj, ...) + +Extends a destination object with the properties of some source objects. + +```lua +_.extend({},{a = 'b', c = 'd'}) -- => "{a = 'b', c = 'd'}" +```` + +### functions (obj, recurseMt) +*Aliases: `_.methods`*. + +Returns all functions names within an object. + +```lua +_.functions(coroutine) -- => "{'create','resume','running','status','wrap','yield'}" +```` + +### clone (obj, shallow) + +Clones a given object. + +```lua +local obj = {1,2,3} +local obj2 = _.clone(obj) +print(obj2 == obj) -- => false +print(_.isEqual(obj2, obj)) -- => true +```` + +### tap (obj, f, ...) + +Invokes a given interceptor function on some object, and then returns the object itself. Useful to tap into method chaining to hook intermediate results. +The pased-interceptor is prototyped as `f(obj,...)`. + +```lua +local v = _.chain({1,2,3,4,5,6,7,8,9,10) + :filter(function(k,v) return v%2~=0 end) -- filters even values + :tap(function(v) print('Max is', _.max(v) end) -- Tap max values + :map(function(k,v) return k^2) + :value() -- => Max is 9 +```` + +### has (obj, key) + +Checks if an object has a given attribute. + +```lua +_.has(_,'has') -- => true +_.has(coroutine,'resume') -- => true +_.has(math,'random') -- => true +```` + +### pick (obj, ...) +*Aliases: `_.choose`*. + +Collects whilelisted properties of a given object. + +```lua +local object = {a = 1, b = 2, c = 3} +_.pick(object,'a','c') -- => "{a = 1, c = 3}" +```` + +### omit (obj, ...) +*Aliases: `_.drop`*. + +Omits blacklisted properties of a given object. + +```lua +local object = {a = 1, b = 2, c = 3} +_.omit(object,'a','c') -- => "{b = 2}" +```` + +### template (obj, template) +*Aliases: `_.defaults`*. + +Applies a template on an object, preserving existing properties. + +```lua +local obj = {a = 0} +_.template(obj,{a = 1, b = 2, c = 3}) -- => "{a=0, c=3, b=2}" +```` + +### isEqual (objA, objB, useMt) +*Aliases: `_.compare`*. + +Compares objects: + +```lua +_.isEqual(1,1) -- => true +_.isEqual(true,false) -- => false +_.isEqual(3.14,math.pi) -- => false +_.isEqual({3,4,5},{3,4,{5}}) -- => false +```` + +### result (obj, method, ...) + +Calls an object method, passing it as a first argument the object itself. + +```lua +_.result('abc','len') -- => 3 +_.result({'a','b','c'},table.concat) -- => 'abc' +```` + +### isTable (t) + +Is the given argument an object (i.e a table) ? + +```lua +_.isTable({}) -- => true +_.isTable(math) -- => true +_.isTable(string) -- => true +```` + +### isCallable (obj) + +Is the given argument callable ? + +```lua +_.isCallable(print) -- => true +_.isCallable(function() end) -- => true +_.isCallable(setmetatable({},{__index = string}).upper) -- => true +_.isCallable(setmetatable({},{__call = function() return end})) -- => true +```` + +### isArray (obj) + +Is the given argument an array (i.e. a sequence) ? + +```lua +_.isArray({}) -- => true +_.isArray({1,2,3}) -- => true +_.isArray({'a','b','c'}) -- => true +```` + +### isIterable (obj) + +Checks if the given object is iterable with `pairs`. + +```lua +_.isIterable({}) -- => true +_.isIterable(function() end) -- => false +_.isIterable(false) -- => false +_.isIterable(1) -- => false +```` + +### isEmpty (obj) + +Is the given argument empty ? + +```lua +_.isEmpty('') -- => true +_.isEmpty({}) -- => true +_.isEmpty({'a','b','c'}) -- => false +```` + +### isString (obj) + +Is the given argument a string ? + +```lua +_.isString('') -- => true +_.isString('Hello') -- => false +_.isString({}) -- => false +```` + +### isFunction (obj) + +Is the given argument a function ? + +```lua +_.isFunction(print) -- => true +_.isFunction(function() end) -- => true +_.isFunction({}) -- => false +```` + +### isNil (obj) + +Is the given argument nil ? + +```lua +_.isNil(nil) -- => true +_.isNil() -- => true +_.isNil({}) -- => false +```` + +### isNumber (obj) + +Is the given argument a number ? + +```lua +_.isNumber(math.pi) -- => true +_.isNumber(math.huge) -- => true +_.isNumber(0/0) -- => true +_.isNumber() -- => false +```` + +### isNaN (obj) + +Is the given argument NaN ? + +```lua +_.isNaN(1) -- => false +_.isNaN(0/0) -- => true +```` + +### isFinite (obj) + +Is the given argument a finite number ? + +```lua +_.isFinite(99e99) -- => true +_.isFinite(math.pi) -- => true +_.isFinite(math.huge) -- => false +_.isFinite(1/0) -- => false +_.isFinite(0/0) -- => false +```` + +### isBoolean (obj) + +Is the given argument a boolean ? + +```lua +_.isBoolean(true) -- => true +_.isBoolean(false) -- => true +_.isBoolean(1==1) -- => true +_.isBoolean(print) -- => false +```` + +### isInteger (obj) + +Is the given argument an integer ? + +```lua +_.isInteger(math.pi) -- => false +_.isInteger(1) -- => true +_.isInteger(-1) -- => true +```` + +**[[⬆]](#TOC)** + +## Chaining + +*Method chaining* (also known as *name parameter idiom*), is a technique for invoking consecutively method calls in object-oriented style. +Each method returns an object, and methods calls are chained together. +Moses offers chaining for your perusal.
+Let's use chaining to get the count of evey single word in some lyrics (case won't matter here). + + +```lua +local lyrics = { + "I am a lumberjack and I am okay", + "I sleep all night and I work all day", + "He is a lumberjack and he is okay", + "He sleeps all night and he works all day" +} + +local stats = _.chain(lyrics) + :map(function(k,line) + local t = {} + for w in line:gmatch('(%w+)') do + t[#t+1] = w + end + return t + end) + :flatten() + :countBy(function(i,v) return v:lower() end) + :value() + +-- => "{ +-- => sleep = 1, night = 2, works = 1, am = 2, is = 2, +-- => he = 2, and = 4, I = 4, he = 2, day = 2, a = 2, +-- => work = 1, all = 4, okay = 2 +-- => }" +```` + +For convenience, you can also use `_(value)` to start chaining methods, instead of `_.chain(value)`. + +Note that one can use `:value()` to unwrap a chained object. + +```lua +local t = {1,2,3} +print(_(t):value() == t) -- => true +```` + +**[[⬆]](#TOC)** + +## Import + +All library functions can be imported in a context using `import` into a specified context. + +```lua +local context = {} +_.import(context) + +context.each({1,2,3},print) + +-- => 1 1 +-- => 2 2 +-- => 3 3 +```` + +When no `context` was provided, it defaults to the global environment `_G`. + +```lua +_.import() + +each({1,2,3},print) + +-- => 1 1 +-- => 2 2 +-- => 3 3 +```` + +Passing `noConflict` argument leaves untouched conflicting keys while importing into the context. + +```lua +local context = {each = 1} +_.import(context, true) + +print(context.each) -- => 1 +context.eachi({1,2,3},print) + +-- => 1 1 +-- => 2 2 +-- => 3 3 +```` + +**[[⬆]](#TOC)** \ No newline at end of file diff --git a/files/lua/moses.lua b/files/lua/moses.lua new file mode 100644 index 0000000..55e851c --- /dev/null +++ b/files/lua/moses.lua @@ -0,0 +1,1797 @@ +--- *Utility-belt library for functional programming in Lua.*
+-- Source on [Github](http://github.com/Yonaba/Moses) +-- @author [Roland Yonaba](http://github.com/Yonaba) +-- @copyright 2012-2014 +-- @license [MIT](http://www.opensource.org/licenses/mit-license.php) +-- @release 1.4.0 +-- @module moses + +local _MODULEVERSION = '1.4.0' + +-- Internalisation +local next, type, unpack, select, pcall = next, type, unpack, select, pcall +local setmetatable, getmetatable = setmetatable, getmetatable +local t_insert, t_sort = table.insert, table.sort +local t_remove,t_concat = table.remove, table.concat +local randomseed, random, huge = math.randomseed, math.random, math.huge +local floor, max, min = math.floor, math.max, math.min +local rawget = rawget +local unpack = unpack +local pairs,ipairs = pairs,ipairs +local _ = {} + + +-- ======== Private helpers + +local function f_max(a,b) return a>b end +local function f_min(a,b) return ab and b or var) end +local function isTrue(_,value) return value and true end +local function iNot(value) return not value end + +local function count(t) -- raw count of items in an map-table + local i = 0 + for k,v in pairs(t) do i = i + 1 end + return i +end + +local function extract(list,comp,transform,...) -- extracts value from a list + local _ans + local transform = transform or _.identity + for index,value in pairs(list) do + if not _ans then _ans = transform(value,...) + else + local value = transform(value,...) + _ans = comp(_ans,value) and _ans or value + end + end + return _ans +end + +local function partgen(t, n, f) -- generates array partitions + for i = 0, #t, n do + local s = _.slice(t, i+1, i+n) + if #s>0 then f(s) end + end +end + +local function permgen(t, n, f) -- taken from PiL: http://www.lua.org/pil/9.3.html + if n == 0 then f(t) end + for i = 1,n do + t[n], t[i] = t[i], t[n] + permgen(t, n-1, f) + t[n], t[i] = t[i], t[n] + end +end + +-- Internal counter for unique ids generation +local unique_id_counter = -1 + +--- Table functions +-- @section Table functions + +--- Iterates on each key-value pairs in a table. Calls function `f(key, value)` at each step of iteration. +--
Aliased as `forEach`. +-- @name each +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @see eachi +function _.each(t, f, ...) + for index,value in pairs(t) do + f(index,value,...) + end +end + +--- Iterates on each integer key-value pairs in a table. Calls function `f(key, value)` +-- only on values at integer key in a given collection. The table can be a sparse array, +-- or map-like. Iteration will start from the lowest integer key found to the highest one. +--
Aliased as `forEachi`. +-- @name eachi +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @see each +function _.eachi(t, f, ...) + local lkeys = _.sort(_.select(_.keys(t), function(k,v) + return _.isInteger(v) + end)) + for k, key in ipairs(lkeys) do + f(key, t[key],...) + end +end + +--- Returns an array of values at specific indexes and keys. +-- @name at +-- @tparam table t a table +-- @tparam vararg ... A variable number of indexes or keys to extract values +-- @treturn table an array-list of values from the passed-in table +function _.at(t, ...) + local values = {} + for i, key in ipairs({...}) do + if _.has(t, key) then values[#values+1] = t[key] end + end + return values +end + +--- Counts occurrences of a given value in a table. Uses @{isEqual} to compare values. +-- @name count +-- @tparam table t a table +-- @tparam[opt] value value a value to be searched in the table. If not given, the @{size} of the table will be returned +-- @treturn number the count of occurrences of `value` +-- @see countf +-- @see size +function _.count(t, value) + if _.isNil(value) then return _.size(t) end + local count = 0 + _.each(t, function(k,v) + if _.isEqual(v, value) then count = count + 1 end + end) + return count +end + +--- Counts occurrences validating a predicate. Same as @{count}, but uses an iterator. +-- Returns the count for values passing the test `f(key, value, ...)` +-- @name countf +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @treturn number the count of values validating the predicate +-- @see count +-- @see size +function _.countf(t, f, ...) + return _.count(_.map(t, f, ...), true) +end + +--- Iterates through a table and loops `n` times. The full iteration loop will be +-- repeated `n` times (or forever, if `n` is omitted). In case `n` is lower or equal to 0, it returns +-- an empty function. +--
Aliased as `loop`. +-- @name cycle +-- @tparam table t a table +-- @tparam number n the number of loops +-- @treturn function an iterator function yielding key-value pairs from the passed-in table. +function _.cycle(t, n) + n = n or 1 + if n<=0 then return function() end end + local k, fk + local i = 0 + while true do + return function() + k = k and next(t,k) or next(t) + fk = not fk and k or fk + if n then + i = (k==fk) and i+1 or i + if i > n then + return + end + end + return k, t[k] + end + end +end + +--- Maps function `f(key, value)` on all key-value pairs. Collects +-- and returns the results as a table. +--
Aliased as `collect`. +-- @name map +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @treturn table a table of results +function _.map(t, f, ...) + local _t = {} + for index,value in pairs(t) do + _t[index] = f(index,value,...) + end + return _t +end + +--- Reduces a table, left-to-right. Folds the table from the first element to the last element +-- to into a single value, with respect to a given iterator and an initial state. +-- The given function takes a state and a value and returns a new state. +--
Aliased as `inject`, `foldl`. +-- @name reduce +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(state, value)` +-- @tparam[opt] state state an initial state of reduction. Defaults to the first value in the table. +-- @treturn state state the final state of reduction +-- @see reduceRight +function _.reduce(t, f, state) + for __,value in pairs(t) do + if state == nil then state = value + else state = f(state,value) + end + end + return state +end + +--- Reduces a table, right-to-left. Folds the table from the last element to the first element +-- to single value, with respect to a given iterator and an initial state. +-- The given function takes a state and a value, and returns a new state. +--
Aliased as `injectr`, `foldr`. +-- @name reduceRight +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(state,value)` +-- @tparam[opt] state state an initial state of reduction. Defaults to the last value in the table. +-- @treturn state state the final state of reduction +-- @see reduce +function _.reduceRight(t, f, state) + return _.reduce(_.reverse(t),f,state) +end + +--- Reduces a table while saving intermediate states. Folds the table left-to-right +-- to a single value, with respect to a given iterator and an initial state. The given function +-- takes a state and a value, and returns a new state. It returns an array of intermediate states. +--
Aliased as `mapr` +-- @name mapReduce +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(state, value)` +-- @tparam[opt] state state an initial state of reduction. Defaults to the first value in the table. +-- @treturn table an array of states +-- @see mapReduceRight +function _.mapReduce(t, f, state) + local _t = {} + for i,value in pairs(t) do + _t[i] = not state and value or f(state,value) + state = _t[i] + end + return _t +end + +--- Reduces a table while saving intermediate states. Folds the table right-to-left +-- to a single value, with respect to a given iterator and an initial state. The given function +-- takes a state and a value, and returns a new state. It returns an array of intermediate states. +--
Aliased as `maprr` +-- @name mapReduceRight +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(state,value)` +-- @tparam[opt] state state an initial state of reduction. Defaults to the last value in the table. +-- @treturn table an array of states +-- @see mapReduce +function _.mapReduceRight(t, f, state) + return _.mapReduce(_.reverse(t),f,state) +end + +--- Search for a value in a table. It does not search in nested tables. +--
Aliased as `any`, `some` +-- @name include +-- @tparam table t a table +-- @tparam value|function value a value to search for +-- @treturn boolean a boolean : `true` when found, `false` otherwise +-- @see detect +-- @see contains +function _.include(t,value) + local _iter = _.isFunction(value) and value or _.isEqual + for __,v in pairs(t) do + if _iter(v,value) then return true end + end + return false +end + +--- Search for a value in a table. Returns the key of the value if found. +-- It does not search in nested tables. +-- @name detect +-- @tparam table t a table +-- @tparam value value a value to search for +-- @treturn key the value key or __nil__ +-- @see include +-- @see contains +function _.detect(t, value) + local _iter = _.isFunction(value) and value or _.isEqual + for key,arg in pairs(t) do + if _iter(arg,value) then return key end + end +end + +--- Checks if a value is present in a table. +-- @name contains +-- @tparam table t a table +-- @tparam value value a value to search for +-- @treturn boolean true if present, otherwise false +-- @see include +-- @see detect +function _.contains(t, value) + return _.toBoolean(_.detect(t, value)) +end + +--- Returns the first value having specified keys `props`. +-- @function findWhere +-- @tparam table t a table +-- @tparam table props a set of keys +-- @treturn value a value from the passed-in table +function _.findWhere(t, props) + local index = _.detect(t, function(v) + for key in pairs(props) do + if props[key] ~= v[key] then return false end + end + return true + end) + return index and t[index] +end + +--- Selects and extracts values passing an iterator test. +--
Aliased as `filter`. +-- @name select +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @treturn table the selected values +-- @see reject +function _.select(t, f, ...) + local _mapped = _.map(t, f, ...) + local _t = {} + for index,value in pairs(_mapped) do + if value then _t[#_t+1] = t[index] end + end + return _t +end + +--- Clones a table while dropping values passing an iterator test. +--
Aliased as `discard` +-- @name reject +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @treturn table the remaining values +-- @see select +function _.reject(t, f, ...) + local _mapped = _.map(t,f,...) + local _t = {} + for index,value in pairs (_mapped) do + if not value then _t[#_t+1] = t[index] end + end + return _t +end + +--- Checks if all values in a table are passing an iterator test. +--
Aliased as `every` +-- @name all +-- @tparam table t a table +-- @tparam function f an iterator function, prototyped as `f(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @treturn boolean `true` if all values passes the predicate, `false` otherwise +function _.all(t, f, ...) + return ((#_.select(_.map(t,f,...), isTrue)) == (#t)) +end + +--- Invokes a method on each value in a table. +-- @name invoke +-- @tparam table t a table +-- @tparam function method a function, prototyped as `f(value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `method` +-- @treturn result the result(s) of method call `f(value, ...)` +-- @see pluck +function _.invoke(t, method, ...) + local args = {...} + return _.map(t, function(__,v) + if _.isTable(v) then + if _.has(v,method) then + if _.isCallable(v[method]) then + return v[method](v,unpack(args)) + else + return v[method] + end + else + if _.isCallable(method) then + return method(v,unpack(args)) + end + end + elseif _.isCallable(method) then + return method(v,unpack(args)) + end + end) +end + +--- Extracts property-values from a table of values. +-- @name pluck +-- @tparam table t a table +-- @tparam string a property, will be used to index in each value: `value[property]` +-- @treturn table an array of values for the specified property +function _.pluck(t, property) + return _.reject(_.map(t,function(__,value) + return value[property] + end), iNot) +end + +--- Returns the max value in a collection. If an transformation function is passed, it will +-- be used to extract the value by which all objects will be sorted. +-- @name max +-- @tparam table t a table +-- @tparam[opt] function transform an transformation function, prototyped as `transform(value,...)`, defaults to @{identity} +-- @tparam[optchain] vararg ... Optional extra-args to be passed to function `transform` +-- @treturn value the maximum value found +-- @see min +function _.max(t, transform, ...) + return extract(t, f_max, transform, ...) +end + +--- Returns the min value in a collection. If an transformation function is passed, it will +-- be used to extract the value by which all objects will be sorted. +-- @name min +-- @tparam table t a table +-- @tparam[opt] function transform an transformation function, prototyped as `transform(value,...)`, defaults to @{identity} +-- @tparam[optchain] vararg ... Optional extra-args to be passed to function `transform` +-- @treturn value the minimum value found +-- @see max +function _.min(t, transform, ...) + return extract(t, f_min, transform, ...) +end + +--- Returns a shuffled copy of a given collection. If a seed is provided, it will +-- be used to init the random number generator (via `math.randomseed`). +-- @name shuffle +-- @tparam table t a table +-- @tparam[opt] number seed a seed +-- @treturn table a shuffled copy of the given table +function _.shuffle(t, seed) + if seed then randomseed(seed) end + local _shuffled = {} + _.each(t,function(index,value) + local randPos = floor(random()*index)+1 + _shuffled[index] = _shuffled[randPos] + _shuffled[randPos] = value + end) + return _shuffled +end + +--- Checks if two tables are the same. It compares if both tables features the same values, +-- but not necessarily at the same keys. +-- @name same +-- @tparam table a a table +-- @tparam table b another table +-- @treturn boolean `true` or `false` +function _.same(a, b) + return _.all(a, function (i,v) return _.include(b,v) end) + and _.all(b, function (i,v) return _.include(a,v) end) +end + +--- Sorts a table, in-place. If a comparison function is given, it will be used to sort values. +-- @name sort +-- @tparam table t a table +-- @tparam[opt] function comp a comparison function prototyped as `comp(a,b)`, defaults to < operator. +-- @treturn table the given table, sorted. +function _.sort(t, comp) + t_sort(t, comp) + return t +end + +--- Splits a table into subsets. Each subset feature values from the original table grouped +-- by the result of passing it through an iterator. +-- @name groupBy +-- @tparam table t a table +-- @tparam function iter an iterator function, prototyped as `iter(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `iter` +-- @treturn table a new table with values grouped by subsets +function _.groupBy(t, iter, ...) + local vararg = {...} + local _t = {} + _.each(t, function(i,v) + local _key = iter(i,v, unpack(vararg)) + if _t[_key] then _t[_key][#_t[_key]+1] = v + else _t[_key] = {v} + end + end) + return _t +end + +--- Groups values in a collection and counts them. +-- @name countBy +-- @tparam table t a table +-- @tparam function iter an iterator function, prototyped as `iter(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `iter` +-- @treturn table a new table with subsets names paired with their count +function _.countBy(t, iter, ...) + local vararg = {...} + local stats = {} + _.each(t,function(i,v) + local key = iter(i,v,unpack(vararg)) + stats[key] = (stats[key] or 0) +1 + end) + return stats +end + +--- Counts the number of values in a collection. If being passed more than one args +-- it will return the count of all passed-in args. +-- @name size +-- @tparam[opt] vararg ... Optional variable number of arguments +-- @treturn number a count +-- @see count +-- @see countf +function _.size(...) + local args = {...} + local arg1 = args[1] + if _.isNil(arg1) then + return 0 + elseif _.isTable(arg1) then + return count(args[1]) + else + return count(args) + end +end + +--- Checks if all the keys of `other` table exists in table `t`. It does not +-- compares values. The test is not commutative, i.e table `t` may contains keys +-- not existing in `other`. +-- @name containsKeys +-- @tparam table t a table +-- @tparam table other another table +-- @treturn boolean `true` or `false` +-- @see sameKeys +function _.containsKeys(t, other) + for key in pairs(other) do + if not t[key] then return false end + end + return true +end + +--- Checks if both given tables have the same keys. It does not compares values. +-- @name sameKeys +-- @tparam table tA a table +-- @tparam table tB another table +-- @treturn boolean `true` or `false` +-- @see containsKeys +function _.sameKeys(tA, tB) + _.each(tA,function(key) + if not tB[key] then return false end + end) + _.each(tB,function(key) + if not tA[key] then return false end + end) + return true +end + + +--- Array functions +-- @section Array functions + +--- Converts a vararg list to an array-list. +-- @name toArray +-- @tparam[opt] vararg ... Optional variable number of arguments +-- @treturn table an array-list of all passed-in args +function _.toArray(...) return {...} end + +--- Looks for the first occurrence of a given value in an array. Returns the value index if found. +-- @name find +-- @tparam table array an array of values +-- @tparam value value a value to search for +-- @tparam[opt] number from the index from where to start the search. Defaults to 1. +-- @treturn number|nil the index of the value if found in the array, `nil` otherwise. +function _.find(array, value, from) + for i = from or 1, #array do + if _.isEqual(array[i], value) then return i end + end +end + +--- Reverses values in a given array. The passed-in array should not be sparse. +-- @name reverse +-- @tparam table array an array +-- @treturn table a copy of the given array, reversed +function _.reverse(array) + local _array = {} + for i = #array,1,-1 do + _array[#_array+1] = array[i] + end + return _array +end + +--- Collects values from a given array. The passed-in array should not be sparse. +-- This function collects values as long as they satisfy a given predicate. +-- Therefore, it returns on the first falsy test. +--
Aliased as `takeWhile` +-- @name selectWhile +-- @tparam table array an array +-- @tparam function f an iterator function prototyped as `f(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @treturn table a new table containing all values collected +-- @see dropWhile +function _.selectWhile(array, f, ...) + local t = {} + for i,v in ipairs(array) do + if f(i,v,...) then t[i] = v else break end + end + return t +end + +--- Collects values from a given array. The passed-in array should not be sparse. +-- This function collects values as long as they do not satisfy a given predicate. +-- Therefore it returns on the first true test. +--
Aliased as `rejectWhile` +-- @name dropWhile +-- @tparam table array an array +-- @tparam function f an iterator function prototyped as `f(key,value,...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @treturn table a new table containing all values collected +-- @selectWhile +function _.dropWhile(array, f, ...) + local _i + for i,v in ipairs(array) do + if not f(i,v,...) then + _i = i + break + end + end + if _.isNil(_i) then return {} end + return _.rest(array,_i) +end + +--- Returns the index at which a value should be inserted. This returned index is determined so +-- that it maintains the sort. If a comparison function is passed, it will be used to sort all +-- values. +-- @name sortedIndex +-- @tparam table array an array +-- @tparam value the value to be inserted +-- @tparam[opt] function comp an comparison function prototyped as `f(a, b)`, defaults to < operator. +-- @tparam[optchain] boolean sort whether or not the passed-in array should be sorted +-- @treturn number the index at which the passed-in value should be inserted +function _.sortedIndex(array, value, comp, sort) + local _comp = comp or f_min + if sort then _.sort(array,_comp) end + for i = 1,#array do + if not _comp(array[i],value) then return i end + end + return #array+1 +end + +--- Returns the index of a given value in an array. If the passed-in value exists +-- more than once in the array, it will return the index of the first occurrence. +-- @name indexOf +-- @tparam table array an array +-- @tparam value the value to search for +-- @treturn number|nil the index of the passed-in value +-- @see lastIndexOf +function _.indexOf(array, value) + for k = 1,#array do + if array[k] == value then return k end + end +end + +--- Returns the index of the last occurrence of a given value. +-- @name lastIndexOf +-- @tparam table array an array +-- @tparam value the value to search for +-- @treturn number|nil the index of the last occurrence of the passed-in value or __nil__ +-- @see indexOf +function _.lastIndexOf(array, value) + local key = _.indexOf(_.reverse(array),value) + if key then return #array-key+1 end +end + +--- Adds all passed-in values at the top of an array. The last arguments will bubble to the +-- top of the given array. +-- @name addTop +-- @tparam table array an array +-- @tparam vararg ... a variable number of arguments +-- @treturn table the passed-in array +-- @see push +function _.addTop(array, ...) + _.each({...},function(i,v) t_insert(array,1,v) end) + return array +end + +--- Pushes all passed-in values at the end of an array. +-- @name push +-- @tparam table array an array +-- @tparam vararg ... a variable number of arguments +-- @treturn table the passed-in array +-- @see addTop +function _.push(array, ...) + _.each({...}, function(i,v) array[#array+1] = v end) + return array +end + +--- Removes and returns the values at the top of a given array. +--
Aliased as `shift` +-- @name pop +-- @tparam table array an array +-- @tparam[opt] number n the number of values to be popped. Defaults to 1. +-- @treturn vararg a vararg list of values popped from the array +-- @see unshift +function _.pop(array, n) + n = min(n or 1, #array) + local ret = {} + for i = 1, n do + local retValue = array[1] + ret[#ret + 1] = retValue + t_remove(array,1) + end + return unpack(ret) +end + +--- Removes and returns the values at the end of a given array. +-- @name unshift +-- @tparam table array an array +-- @tparam[opt] number n the number of values to be unshifted. Defaults to 1. +-- @treturn vararg a vararg list of values +-- @see pop +function _.unshift(array, n) + n = min(n or 1, #array) + local ret = {} + for i = 1, n do + local retValue = array[#array] + ret[#ret + 1] = retValue + t_remove(array) + end + return unpack(ret) +end + +--- Removes all provided values in a given array. +--
Aliased as `remove` +-- @name pull +-- @tparam table array an array +-- @tparam vararg ... a variable number of values to be removed from the array +-- @treturn table the passed-in array +function _.pull(array, ...) + for __, rmValue in ipairs({...}) do + for i = #array, 1, -1 do + if _.isEqual(array[i], rmValue) then + t_remove(array, i) + end + end + end + return array +end + +--- Trims all values indexed within the range `[start, finish]`. +--
Aliased as `rmRange` +-- @name removeRange +-- @tparam table array an array +-- @tparam[opt] number start the lower bound index, defaults to the first index in the array. +-- @tparam[optchain] number finish the upper bound index, defaults to the array length. +-- @treturn table the passed-in array +function _.removeRange(array, start, finish) + local array = _.clone(array) + local i,n = (next(array)),#array + if n < 1 then return array end + + start = clamp(start or i,i,n) + finish = clamp(finish or n,i,n) + + if finish < start then return array end + + local count = finish - start + 1 + local i = start + while count > 0 do + t_remove(array,i) + count = count - 1 + end + return array +end + +--- Chunks together consecutive values. Values are chunked on the basis of the return +-- value of a provided predicate `f(key, value, ...)`. Consecutive elements which return +-- the same value are chunked together. Leaves the first argument untouched if it is not an array. +-- @name chunk +-- @tparam table array an array +-- @tparam function f an iterator function prototyped as `f(key, value, ...)` +-- @tparam[opt] vararg ... Optional extra-args to be passed to function `f` +-- @treturn table a table of chunks (arrays) +-- @see zip +function _.chunk(array, f, ...) + if not _.isArray(array) then return array end + local ch, ck, prev = {}, 0 + local mask = _.map(array, f,...) + _.each(mask, function(k,v) + prev = (prev==nil) and v or prev + ck = ((v~=prev) and (ck+1) or ck) + if not ch[ck] then + ch[ck] = {array[k]} + else + ch[ck][#ch[ck]+1] = array[k] + end + prev = v + end) + return ch +end + +--- Slices values indexed within `[start, finish]` range. +--
Aliased as `_.sub` +-- @name slice +-- @tparam table array an array +-- @tparam[opt] number start the lower bound index, defaults to the first index in the array. +-- @tparam[optchain] number finish the upper bound index, defaults to the array length. +-- @treturn table a new array +function _.slice(array, start, finish) + return _.select(array, function(index) + return (index >= (start or next(array)) and index <= (finish or #array)) + end) +end + +--- Returns the first N values in an array. +--
Aliased as `head`, `take` +-- @name first +-- @tparam table array an array +-- @tparam[opt] number n the number of values to be collected, defaults to 1. +-- @treturn table a new array +-- @see initial +-- @see last +-- @see rest +function _.first(array, n) + local n = n or 1 + return _.slice(array,1, min(n,#array)) +end + +--- Returns all values in an array excluding the last N values. +-- @name initial +-- @tparam table array an array +-- @tparam[opt] number n the number of values to be left, defaults to the array length. +-- @treturn table a new array +-- @see first +-- @see last +-- @see rest +function _.initial(array, n) + if n and n < 0 then return end + return _.slice(array,1, n and #array-(min(n,#array)) or #array-1) +end + +--- Returns the last N values in an array. +-- @name last +-- @tparam table array an array +-- @tparam[opt] number n the number of values to be collected, defaults to the array length. +-- @treturn table a new array +-- @see first +-- @see initial +-- @see rest +function _.last(array,n) + if n and n <= 0 then return end + return _.slice(array,n and #array-min(n-1,#array-1) or 2,#array) +end + +--- Trims all values before index. +--
Aliased as `tail` +-- @name rest +-- @tparam table array an array +-- @tparam[opt] number index an index, defaults to 1 +-- @treturn table a new array +-- @see first +-- @see initial +-- @see last +function _.rest(array,index) + if index and index > #array then return {} end + return _.slice(array,index and max(1,min(index,#array)) or 1,#array) +end + +--- Trims all falsy (false and nil) values. +-- @name compact +-- @tparam table array an array +-- @treturn table a new array +function _.compact(array) + return _.reject(array, function (_,value) + return not value + end) +end + +--- Flattens a nested array. Passing `shallow` will only flatten at the first level. +-- @name flatten +-- @tparam table array an array +-- @tparam[opt] boolean shallow specifies the flattening depth +-- @treturn table a new array, flattened +function _.flatten(array, shallow) + local shallow = shallow or false + local new_flattened + local _flat = {} + for key,value in pairs(array) do + if _.isTable(value) then + new_flattened = shallow and value or _.flatten (value) + _.each(new_flattened, function(_,item) _flat[#_flat+1] = item end) + else _flat[#_flat+1] = value + end + end + return _flat +end + +--- Returns values from an array not present in all passed-in args. +--
Aliased as `without` and `diff` +-- @name difference +-- @tparam table array an array +-- @tparam table another array +-- @treturn table a new array +-- @see union +-- @see intersection +-- @see symmetricDifference +function _.difference(array, array2) + if not array2 then return _.clone(array) end + return _.select(array,function(i,value) + return not _.include(array2,value) + end) +end + +--- Returns the duplicate-free union of all passed in arrays. +-- @name union +-- @tparam vararg ... a variable number of arrays arguments +-- @treturn table a new array +-- @see difference +-- @see intersection +-- @see symmetricDifference +function _.union(...) + return _.uniq(_.flatten({...})) +end + +--- Returns the intersection of all passed-in arrays. +-- Each value in the result is present in each of the passed-in arrays. +-- @name intersection +-- @tparam table array an array +-- @tparam vararg ... a variable number of array arguments +-- @treturn table a new array +-- @see difference +-- @see union +-- @see symmetricDifference +function _.intersection(array, ...) + local arg = {...} + local _intersect = {} + for i,value in ipairs(array) do + if _.all(arg,function(i,v) + return _.include(v,value) + end) then + t_insert(_intersect,value) + end + end + return _intersect +end + +--- Performs a symmetric difference. Returns values from `array` not present in `array2` and also values +-- from `array2` not present in `array`. +--
Aliased as `symdiff` +-- @name symmetricDifference +-- @tparam table array an array +-- @tparam table array2 another array +-- @treturn table a new array +-- @see difference +-- @see union +-- @see intersection +function _.symmetricDifference(array, array2) + return _.difference( + _.union(array, array2), + _.intersection(array,array2) + ) +end + +--- Produces a duplicate-free version of a given array. +--
Aliased as `uniq` +-- @name unique +-- @tparam table array an array +-- @treturn table a new array, duplicate-free +-- @see isunique +function _.unique(array) + local ret = {} + for i = 1, #array do + if not _.find(ret, array[i]) then + ret[#ret+1] = array[i] + end + end + return ret +end + +--- Checks if a given array contains distinct values. Such an array is made of distinct elements, +-- which only occur once in this array. +--
Aliased as `isuniq` +-- @name isunique +-- @tparam table array an array +-- @treturn boolean `true` if the given array is unique, `false` otherwise. +-- @see unique +function _.isunique(array) + return _.isEqual(array, _.unique(array)) +end + +--- Merges values of each of the passed-in arrays in subsets. +-- Only values indexed with the same key in the given arrays are merged in the same subset. +-- @name zip +-- @tparam vararg ... a variable number of array arguments +-- @treturn table a new array +function _.zip(...) + local arg = {...} + local _len = _.max(_.map(arg,function(i,v) + return #v + end)) + local _ans = {} + for i = 1,_len do + _ans[i] = _.pluck(arg,i) + end + return _ans +end + +--- Clones `array` and appends `other` values. +-- @name append +-- @tparam table array an array +-- @tparam table other an array +-- @treturn table a new array +function _.append(array, other) + local t = {} + for i,v in ipairs(array) do t[i] = v end + for i,v in ipairs(other) do t[#t+1] = v end + return t +end + +--- Interleaves arrays. It returns a single array made of values from all +-- passed in arrays in their given order, interleaved. +-- @name interleave +-- @tparam vararg ... a variable list of arrays +-- @treturn table a new array +-- @see interpose +function _.interleave(...) return _.flatten(_.zip(...)) end + +--- Interposes `value` in-between consecutive pair of values in `array`. +-- @name interpose +-- @tparam value value a value +-- @tparam table array an array +-- @treturn table a new array +-- @see interleave +function _.interpose(value, array) + return _.flatten(_.zip(array, _.rep(value, #array-1))) +end + +--- Produce a flexible list of numbers. If one positive value is passed, will count from 0 to that value, +-- with a default step of 1. If two values are passed, will count from the first one to the second one, with the +-- same default step of 1. A third passed value will be considered a step value. +-- @name range +-- @tparam[opt] number from the initial value of the range +-- @tparam[optchain] number to the final value of the range +-- @tparam[optchain] number step the count step value +-- @treturn table a new array of numbers +function _.range(...) + local arg = {...} + local _start,_stop,_step + if #arg==0 then return {} + elseif #arg==1 then _stop,_start,_step = arg[1],0,1 + elseif #arg==2 then _start,_stop,_step = arg[1],arg[2],1 + elseif #arg == 3 then _start,_stop,_step = arg[1],arg[2],arg[3] + end + if (_step and _step==0) then return {} end + local _ranged = {} + local _steps = max(floor((_stop-_start)/_step),0) + for i=1,_steps do _ranged[#_ranged+1] = _start+_step*i end + if #_ranged>0 then t_insert(_ranged,1,_start) end + return _ranged +end + +--- Creates an array list of `n` values, repeated. +-- @name rep +-- @tparam value value a value to be repeated +-- @tparam number n the number of repetitions of the given `value`. +-- @treturn table a new array of `n` values +function _.rep(value, n) + local ret = {} + for i = 1, n do ret[#ret+1] = value end + return ret +end + +--- Iterator returning partitions of an array. It returns arrays of length `n` +-- made of values from the given array. In case the array size is not a multiple +-- of `n`, the last array returned will be made of the rest of the values. +-- @name partition. +-- @tparam table array an array +-- @tparam[opt] number n the size of each partition. Defaults to 1. +-- @treturn function an iterator function +function _.partition(array, n) + return coroutine.wrap(function() + partgen(array, n or 1, coroutine.yield) + end) +end + +--- Iterator returning the permutations of an array. It returns arrays made of all values +-- from the passed-in array, with values permuted. +-- @name permutation +-- @tparam table array an array +-- @treturn function an iterator function +function _.permutation(array) + return coroutine.wrap(function() + permgen(array, #array, coroutine.yield) + end) +end + +--- Swaps keys with values. Produces a new array where previous keys are now values, +-- while previous values are now keys. +--
Aliased as `mirror` +-- @name invert +-- @tparam table array a given array +-- @treturn table a new array +function _.invert(array) + local _ret = {} + _.each(array,function(i,v) _ret[v] = i end) + return _ret +end + +--- Concatenates values in a given array. Handles booleans as well. If `sep` string is +-- passed, it will be used as a separator. Passing `i` and `j` will result in concatenating +-- values within `[i,j]` range. +--
Aliased as `join` +-- @name concat +-- @tparam table array a given array +-- @tparam[opt] string sep a separator string, defaults to `''`. +-- @tparam[optchain] number i the starting index, defaults to 1. +-- @tparam[optchain] number j the final index, defaults to the array length. +-- @treturn string a string +function _.concat(array, sep, i, j) + local _array = _.map(array,function(i,v) + return tostring(v) + end) + return t_concat(_array,sep,i or 1,j or #array) + +end + + +--- Utility functions +-- @section Utility functions + +--- Returns the passed-in value. This function seems useless, but it is used internally +-- as a default iterator. +-- @name identity +-- @tparam value value a value +-- @treturn value the passed-in value +function _.identity(value) return value end + +--- Returns a version of `f` that runs only once. Successive calls to `f` +-- will keep yielding the same output, no matter what the passed-in arguments are. +-- It can be used to initialize variables. +-- @name once +-- @tparam function f a function +-- @treturn function a new function +-- @see after +function _.once(f) + local _internal = 0 + local _args = {} + return function(...) + _internal = _internal+1 + if _internal<=1 then _args = {...} end + return f(unpack(_args)) + end +end + +--- Memoizes a given function by caching the computed result. +-- Useful for speeding-up slow-running functions. If function `hash` is passed, +-- it will be used to compute hash keys for a set of input values to the function for caching. +--
Aliased as `cache` +-- @name memoize +-- @tparam function f a function +-- @tparam[opt] function hash a hash function, defaults to @{identity} +-- @treturn function a new function +function _.memoize(f, hash) + local _cache = setmetatable({},{__mode = 'kv'}) + local _hasher = hash or _.identity + return function (...) + local _hashKey = _hasher(...) + local _result = _cache[_hashKey] + if not _result then _cache[_hashKey] = f(...) end + return _cache[_hashKey] + end +end + +--- Returns a version of `f` that runs on the `count-th` call. +-- Useful when dealing with asynchronous tasks. +-- @name after +-- @tparam function f a function +-- @tparam number count the number of calls before `f` answers +-- @treturn function a new function +-- @see once +function _.after(f, count) + local _limit,_internal = count, 0 + return function(...) + _internal = _internal+1 + if _internal >= _limit then return f(...) end + end +end + +--- Composes functions. Each passed-in function consumes the return value of the function that follows. +-- In math terms, composing the functions `f`, `g`, and `h` produces the function `f(g(h(...)))`. +-- @name compose +-- @tparam vararg ... a variable number of functions +-- @treturn function a new function +-- @see pipe +function _.compose(...) + local f = _.reverse {...} + return function (...) + local _temp + for i, func in ipairs(f) do + _temp = _temp and func(_temp) or func(...) + end + return _temp + end +end + +--- Pipes a value through a series of functions. In math terms, +-- given some functions `f`, `g`, and `h` in that order, it returns `f(g(h(value)))`. +-- @name pipe +-- @tparam value value a value +-- @tparam vararg ... a variable number of functions +-- @treturn value the result of the composition of function calls. +-- @see compose +function _.pipe(value, ...) + return _.compose(...)(value) +end + +--- Returns the logical complement of a given function. For a given input, the returned +-- function will output `false` if the original function would have returned `true`, +-- and vice-versa. +-- @name complement +-- @tparam function f a function +-- @treturn function the logical complement of the given function `f`. +function _.complement(f) + return function(...) return not f(...) end +end + +--- Calls a sequence of passed-in functions with the same argument. +-- Returns a sequence of results. +--
Aliased as `juxt` +-- @name juxtapose +-- @tparam value value a value +-- @tparam vararg ... a variable number of functions +-- @treturn vararg a vargarg list of results. +function _.juxtapose(value, ...) + local res = {} + _.each({...}, function(_,f) res[#res+1] = f(value) end) + return unpack(res) +end + +--- Wraps `f` inside of the `wrapper` function. It passes `f` as the first argument to `wrapper`. +-- This allows the wrapper to execute code before and after `f` runs, +-- adjust the arguments, and execute it conditionally. +-- @name wrap +-- @tparam function f a function to be wrapped, prototyped as `f(...)` +-- @tparam function wrapper a wrapper function, prototyped as `wrapper(f,...)` +-- @treturn function a new function +function _.wrap(f, wrapper) + return function (...) return wrapper(f,...) end +end + +--- Runs `iter` function `n` times. +-- Collects the results of each run and returns them in an array. +-- @name times +-- @tparam number n the number of times `iter` should be called +-- @tparam function iter an iterator function, prototyped as `iter(i, ...)` +-- @tparam vararg ... extra-args to be passed to `iter` function +-- @treturn table an array of results +function _.times(n, iter, ...) + local results = {} + for i = 1,n do + results[i] = iter(i,...) + end + return results +end + +--- Binds `v` to be the first argument to function `f`. As a result, +-- calling `f(...)` will result to `f(v, ...)`. +-- @name bind +-- @tparam function f a function +-- @tparam value v a value +-- @treturn function a function +-- @see bindn +function _.bind(f, v) + return function (...) + return f(v,...) + end +end + +--- Binds `...` to be the N-first arguments to function `f`. As a result, +-- calling `f(a1, a2, ..., aN)` will result to `f(..., a1, a2, ...,aN)`. +-- @name bindn +-- @tparam function f a function +-- @tparam vararg ... a variable number of arguments +-- @treturn function a function +-- @see bind +function _.bindn(f, ...) + local iArg = {...} + return function (...) + return f(unpack(_.append(iArg,{...}))) + end +end + +--- Generates a unique ID for the current session. If given a string *template* +-- will use this template for output formatting. Otherwise, if *template* is a function, +-- will evaluate `template(id, ...)`. +--
Aliased as `uid`. +-- @name uniqueId +-- @tparam[opt] string|function template either a string or a function template to format the ID +-- @tparam[optchain] vararg ... a variable number of arguments to be passed to *template*, in case it is a function. +-- @treturn value an ID +function _.uniqueId(template, ...) + unique_id_counter = unique_id_counter + 1 + if template then + if _.isString(template) then + return template:format(unique_id_counter) + elseif _.isFunction(template) then + return template(unique_id_counter,...) + end + end + return unique_id_counter +end + +--- Object functions +--@section Object functions + +--- Returns the keys of the object properties. +-- @name keys +-- @tparam table obj an object +-- @treturn table an array +function _.keys(obj) + local _oKeys = {} + _.each(obj,function(key) _oKeys[#_oKeys+1]=key end) + return _oKeys +end + +--- Returns the values of the object properties. +-- @name values +-- @tparam table obj an object +-- @treturn table an array +function _.values(obj) + local _oValues = {} + _.each(obj,function(_,value) _oValues[#_oValues+1]=value end) + return _oValues +end + +--- Converts any given value to a boolean +-- @name toBoolean +-- @tparam value value a value. Can be of any type +-- @treturn boolean `true` if value is true, `false` otherwise (false or nil). +function _.toBoolean(value) + return not not value +end + +--- Extends an object properties. It copies all of the properties of extra passed-in objects +-- into the destination object, and returns the destination object. +-- The last object in the `...` set will override properties of the same name in the previous one +-- @name extend +-- @tparam table destObj a destination object +-- @tparam vararg ... a variable number of array arguments +-- @treturn table the destination object extended +function _.extend(destObj, ...) + local sources = {...} + _.each(sources,function(__,source) + if _.isTable(source) then + _.each(source,function(key,value) + destObj[key] = value + end) + end + end) + return destObj +end + +--- Returns a sorted list of all methods names found in an object. If the given object +-- has a metatable implementing an `__index` field pointing to another table, will also recurse on this +-- table if argument `recurseMt` is provided. If `obj` is omitted, it defaults to the library functions. +--
Aliased as `methods`. +-- @name functions +-- @tparam[opt] table obj an object. Defaults to library functions. +-- @treturn table an array-list of methods names +function _.functions(obj, recurseMt) + obj = obj or _ + local _methods = {} + _.each(obj,function(key,value) + if _.isFunction(value) then + _methods[#_methods+1]=key + end + end) + if not recurseMt then + return _.sort(_methods) + end + local mt = getmetatable(obj) + if mt and mt.__index then + local mt_methods = _.functions(mt.__index) + _.each(mt_methods, function(k,fn) + _methods[#_methods+1] = fn + end) + end + return _.sort(_methods) +end + +--- Clones a given object properties. If `shallow` is passed +-- will also clone nested array properties. +-- @name clone +-- @tparam table obj an object +-- @tparam[opt] boolean shallow whether or not nested array-properties should be cloned, defaults to false. +-- @treturn table a copy of the passed-in object +function _.clone(obj, shallow) + if not _.isTable(obj) then return obj end + local _obj = {} + _.each(obj,function(i,v) + if _.isTable(v) then + if not shallow then + _obj[i] = _.clone(v,shallow) + else _obj[i] = v + end + else + _obj[i] = v + end + end) + return _obj +end + +--- Invokes interceptor with the object, and then returns object. +-- The primary purpose of this method is to "tap into" a method chain, in order to perform operations +-- on intermediate results within the chain. +-- @name tap +-- @tparam table obj an object +-- @tparam function f an interceptor function, should be prototyped as `f(obj, ...)` +-- @tparam[opt] vararg ... Extra-args to be passed to interceptor function +-- @treturn table the passed-in object +function _.tap(obj, f, ...) + f(obj,...) + return obj +end + +--- Checks if a given object implements a property. +-- @name has +-- @tparam table obj an object +-- @tparam value key a key property to be checked +-- @treturn boolean `true` or `false` +function _.has(obj, key) + return obj[key]~=nil +end + +--- Return a filtered copy of the object. The returned object will only have +-- the white-listed properties paired with their original values. +--
Aliased as `choose`. +-- @name pick +-- @tparam table obj an object +-- @tparam vararg ... a variable number of string keys +-- @treturn table the filtered object +function _.pick(obj, ...) + local whitelist = _.flatten {...} + local _picked = {} + _.each(whitelist,function(key,property) + if not _.isNil(obj[property]) then + _picked[property] = obj[property] + end + end) + return _picked +end + +--- Return a filtered copy of the object. The returned object will not have +-- the black-listed properties. +--
Aliased as `drop`. +-- @name omit +-- @tparam table obj an object +-- @tparam vararg ... a variable number of string keys +-- @treturn table the filtered object +function _.omit(obj, ...) + local blacklist = _.flatten {...} + local _picked = {} + _.each(obj,function(key,value) + if not _.include(blacklist,key) then + _picked[key] = value + end + end) + return _picked +end + +--- Fills nil properties in an object with the given `template` object. Pre-existing +-- properties will be preserved. +--
Aliased as `defaults`. +-- @name template +-- @tparam table obj an object +-- @tparam[opt] table template a template object. Defaults to an empty table `{}`. +-- @treturn table the passed-in object filled +function _.template(obj, template) + _.each(template or {},function(i,v) + if not obj[i] then obj[i] = v end + end) + return obj +end + +--- Performs a deep comparison test between two objects. Can compare strings, functions +-- (by reference), nil, booleans. Compares tables by reference or by values. If `useMt` +-- is passed, the equality operator `==` will be used if one of the given objects has a +-- metatable implementing `__eq`. +--
Aliased as `_.compare` +-- @name isEqual +-- @tparam table objA an object +-- @tparam table objB another object +-- @tparam[opt] boolean useMt whether or not `__eq` should be used, defaults to false. +-- @treturn boolean `true` or `false` +function _.isEqual(objA, objB, useMt) + local typeObjA = type(objA) + local typeObjB = type(objB) + + if typeObjA~=typeObjB then return false end + if typeObjA~='table' then return (objA==objB) end + + local mtA = getmetatable(objA) + local mtB = getmetatable(objB) + + if useMt then + if (mtA or mtB) and (mtA.__eq or mtB.__eq) then + return mtA.__eq(objA, objB) or mtB.__eq(objB, objA) or (objA==objB) + end + end + + if _.size(objA)~=_.size(objB) then return false end + + for i,v1 in pairs(objA) do + local v2 = objB[i] + if _.isNil(v2) or not _.isEqual(v1,v2,useMt) then return false end + end + + for i,v1 in pairs(objB) do + local v2 = objA[i] + if _.isNil(v2) then return false end + end + + return true +end + +--- Invokes an object method. It passes the object itself as the first argument. if `method` is not +-- callable, will return `obj[method]`. +-- @name result +-- @tparam table obj an object +-- @tparam string method a string key to index in object `obj`. +-- @tparam[opt] vararg ... Optional extra-args to be passed to `method` +-- @treturn value the returned value of `method(obj,...)` call +function _.result(obj, method, ...) + if obj[method] then + if _.isCallable(obj[method]) then + return obj[method](obj,...) + else return obj[method] + end + end + if _.isCallable(method) then + return method(obj,...) + end +end + +--- Checks if the given arg is a table. +-- @name isTable +-- @tparam table t a value to be tested +-- @treturn boolean `true` or `false` +function _.isTable(t) + return type(t) == 'table' +end + +--- Checks if the given argument is an callable. Assumes `obj` is callable if +-- it is either a function or a table having a metatable implementing `__call` metamethod. +-- @name isCallable +-- @tparam table obj an object +-- @treturn boolean `true` or `false` +function _.isCallable(obj) + return (_.isFunction(obj) or + (_.isTable(obj) and getmetatable(obj) + and getmetatable(obj).__call~=nil) or false) +end + +--- Checks if the given argument is an array. Assumes `obj` is an array +-- if is a table with integer numbers starting at 1. +-- @name isArray +-- @tparam table obj an object +-- @treturn boolean `true` or `false` +function _.isArray(obj) + if not _.isTable(obj) then return false end + -- Thanks @Wojak and @Enrique García Cota for suggesting this + -- See : http://love2d.org/forums/viewtopic.php?f=3&t=77255&start=40#p163624 + local i = 0 + for __ in pairs(obj) do + i = i + 1 + if _.isNil(obj[i]) then return false end + end + return true +end + +--- Checks if the given object is iterable with `pairs` (or `ipairs`). +-- @name isIterable +-- @tparam table obj an object +-- @treturn boolean `true` if the object can be iterated with `pairs`, `false` otherwise +function _.isIterable(obj) + return _.toBoolean((pcall(pairs, obj))) +end + +--- Checks if the given is empty. If `obj` is a *string*, will return `true` +-- if `#obj == 0`. Otherwise, if `obj` is a table, will return whether or not this table +-- is empty. If `obj` is `nil`, it will return true. +-- @name isEmpty +-- @tparam[opt] table|string obj an object +-- @treturn boolean `true` or `false` +function _.isEmpty(obj) + if _.isNil(obj) then return true end + if _.isString(obj) then return #obj==0 end + if _.isTable(obj) then return next(obj)==nil end + return true +end + +--- Checks if the given argument is a *string*. +-- @name isString +-- @tparam table obj an object +-- @treturn boolean `true` or `false` +function _.isString(obj) + return type(obj) == 'string' +end + +--- Checks if the given argument is a function. +-- @name isFunction +-- @tparam table obj an object +-- @treturn boolean `true` or `false` +function _.isFunction(obj) + return type(obj) == 'function' +end + +--- Checks if the given argument is nil. +-- @name isNil +-- @tparam table obj an object +-- @treturn boolean `true` or `false` +function _.isNil(obj) + return obj==nil +end + +--- Checks if the given argument is a number. +-- @name isNumber +-- @tparam table obj a number +-- @treturn boolean `true` or `false` +-- @see isNaN +function _.isNumber(obj) + return type(obj) == 'number' +end + +--- Checks if the given argument is NaN (see [Not-A-Number](http://en.wikipedia.org/wiki/NaN)). +-- @name isNaN +-- @tparam table obj a number +-- @treturn boolean `true` or `false` +-- @see isNumber +function _.isNaN(obj) + return _.isNumber(obj) and obj~=obj +end + +--- Checks if the given argument is a finite number. +-- @name isFinite +-- @tparam table obj a number +-- @treturn boolean `true` or `false` +function _.isFinite(obj) + if not _.isNumber(obj) then return false end + return obj > -huge and obj < huge +end + +--- Checks if the given argument is a boolean. +-- @name isBoolean +-- @tparam table obj a boolean +-- @treturn boolean `true` or `false` +function _.isBoolean(obj) + return type(obj) == 'boolean' +end + +--- Checks if the given argument is an integer. +-- @name isInteger +-- @tparam table obj a number +-- @treturn boolean `true` or `false` +function _.isInteger(obj) + return _.isNumber(obj) and floor(obj)==obj +end + +-- Aliases + +do + + -- Table functions aliases + _.forEach = _.each + _.forEachi = _.eachi + _.loop = _.cycle + _.collect = _.map + _.inject = _.reduce + _.foldl = _.reduce + _.injectr = _.reduceRight + _.foldr = _.reduceRight + _.mapr = _.mapReduce + _.maprr = _.mapReduceRight + _.any = _.include + _.some = _.include + _.filter = _.select + _.discard = _.reject + _.every = _.all + + -- Array functions aliases + _.takeWhile = _.selectWhile + _.rejectWhile = _.dropWhile + _.shift = _.pop + _.remove = _.pull + _.rmRange = _.removeRange + _.chop = _.removeRange + _.sub = _.slice + _.head = _.first + _.take = _.first + _.tail = _.rest + _.skip = _.last + _.without = _.difference + _.diff = _.difference + _.symdiff = _.symmetricDifference + _.xor = _.symmetricDifference + _.uniq = _.unique + _.isuniq = _.isunique + _.part = _.partition + _.perm = _.permutation + _.mirror = _.invert + _.join = _.concat + + -- Utility functions aliases + _.cache = _.memoize + _.juxt = _.juxtapose + _.uid = _.uniqueId + + -- Object functions aliases + _.methods = _.functions + _.choose = _.pick + _.drop = _.omit + _.defaults = _.template + _.compare = _.isEqual + +end + +-- Setting chaining and building interface + +do + + -- Wrapper to Moses + local f = {} + + -- Will be returned upon requiring, indexes into the wrapper + local __ = {} + __.__index = f + + -- Wraps a value into an instance, and returns the wrapped object + local function new(value) + local i = {_value = value, _wrapped = true} + return setmetatable(i, __) + end + + setmetatable(__,{ + __call = function(self,v) return new(v) end, -- Calls returns to instantiation + __index = function(t,key,...) return f[key] end -- Redirects to the wrapper + }) + + --- Returns a wrapped object. Calling library functions as methods on this object + -- will continue to return wrapped objects until @{obj:value} is used. Can be aliased as `_(value)`. + -- @class function + -- @name chain + -- @tparam value value a value to be wrapped + -- @treturn object a wrapped object + function __.chain(value) + return new(value) + end + + --- Extracts the value of a wrapped object. Must be called on an chained object (see @{chain}). + -- @class function + -- @name obj:value + -- @treturn value the value previously wrapped + function __:value() + return self._value + end + + -- Register chaining methods into the wrapper + f.chain, f.value = __.chain, __.value + + -- Register all functions into the wrapper + for fname,fct in pairs(_) do + f[fname] = function(v, ...) + local wrapped = _.isTable(v) and v._wrapped or false + if wrapped then + local _arg = v._value + local _rslt = fct(_arg,...) + return new(_rslt) + else + return fct(v,...) + end + end + end + + --- Imports all library functions into a context. + -- @name import + -- @tparam[opt] table context a context. Defaults to `_G` (global environment) when not given. + -- @tparam[optchain] boolean noConflict Skips function import in case its key exists in the given context + -- @treturn table the passed-in context + f.import = function(context, noConflict) + context = context or _G + local funcs = _.functions() + _.each(funcs, function(k, fname) + if rawget(context, fname) then + if not noConflict then + context[fname] = _[fname] + end + else + context[fname] = _[fname] + end + end) + return context + end + + -- Descriptive tags + __._VERSION = 'Moses v'.._MODULEVERSION + __._URL = 'http://github.com/Yonaba/Moses' + __._LICENSE = 'MIT ' + __._DESCRIPTION = 'utility-belt library for functional programming in Lua' + + return __ + +end