Array functions - Yonaba/Moses GitHub Wiki

Array functions

local M = require 'moses'

sample (array [, n = 1 [, seed]])

Samples n values from array.

local array = M.range(1,20)
local sample = M.sample(array, 3)
print(table.concat(sample,','))

-- => {12,11,15}

n defaults to 1. In that case, a single value will be returned.

local array = M.range(1,20)
local sample = M.sample(array)
print(sample)

-- => 12

An optional 3rd argument seed can be passed for deterministic random sampling.

sampleProb (array, prob [, seed])

Returns an array of values randomly selected from a given array. In case seed is provided, it is used for deterministic sampling.

local array = M.range(1,20)
local sample = M.sampleProb(array, 0.2)
print(table.concat(sample,','))

-- => 5,11,12,15

sample = M.sampleProb(array, 0.2, os.time())
print(table.concat(sample,','))

-- => 1,6,10,12,15,20 (or similar)

nsorted (array [, n = 1[, comp]])

Returns the n-top values satisfying a predicate. It takes a comparison function comp used to sort array values, and then picks the top n-values. It leaves the original array untouched.

local function comp(a,b) return a > b end
M.nsorted(array,5, comp) -- => {5,4,3,2,1}

n defaults to 1 and comp defaults to the < operator.

local array = M.range(1,20)
M.nsorted(array) -- => {1}

shuffle (array [, seed])

Shuffles a given array.

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

pack (...)

Converts a vararg list of arguments to an array.

M.pack(1,2,8,'d','a',0) -- => "{1,2,8,'d','a',0}"

find (array, value [, from = 1])

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

local value = {3}
M.find({{4},{3},{2},{1}},value) -- => 2

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

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

reverse (array)

Reverses an array.

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

fill (array, value [, i = 1 [, j = #array]])

Replaces all elements in a given array with a given value.

local array = M.range(1,5)
M.fill(array, 0) -- => {0,0,0,0,0}

It can start replacing value at a specific index.

local array = M.range(1,5)
M.fill(array,0,3) -- => {1,2,0,0,0}

It can replace only values within a specific range.

local array = M.range(1,5)
M.fill(array,0,2,4) -- => {1,0,0,0,5}

In case the upper bound index i greather than the array size, it will enlarge the array.

local array = M.range(1,5)
M.fill(array,0,5,10) -- => {1,2,3,4,0,0,0,0,0,0}

zeros (n)

Returns an array of n zeros.

M.zeros(4) -- => {0,0,0,0}

ones (n)

Returns an array of n 1's.

M.ones(3) -- => {1,1,1}

vector (value, n)

Returns an array of n times a given value.

M.vector(10, 4) -- => {10,10,10,10}

selectWhile (array, f [, ...])

Aliases: takeWhile.

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

M.selectWhile({2,4,5,8}, function(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.

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

sortedIndex (array, value [, comp = math.min [, sort = nil]])

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

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

Can take a custom comparison functions.

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

indexOf (array, value)

Returns the index of a value in an array.

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

lastIndexOf (array, value)

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

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

findIndex (array, pred)

Returns the first index at which a predicate passes a truth test.

local array = {1,2,3,4,5,6}
local function multipleOf3(v) return v%3==0 end
M.findIndex(array, multipleOf3) -- => 3

findLastIndex (array, pred)

Returns the last index at which a predicate passes a truthy test.

local array = {1,2,3,4,5,6}
local function multipleOf3(v) return v%3==0 end
M.findLastIndex(array, multipleOf3) -- => 6

addTop (array, ...)

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

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

prepend (array, ...)

Adds given values at the top of an array, preserving the order at which elements are passed-in.

local array = {'old_val'}
M.prepend(array,1,2,3,4) -- => "{1,2,3,4,'old_val'}"

push (array, ...)

Adds given values at the end of an array.

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

shift (array [, n = 1])

Aliases: pop.

Removes and returns the first value in an array.

local array = {1,2,3}
local shift = M.shift(array) -- => "shift = 1", "array = {2,3}"

If n is supplied, returns n values.

local array = {1,2,3,4,5}
local a, b = M.shift(array, 2) -- => "a = 1, b = 2", "array = {3,4,5}"

unshift (array [, n = 1])

Removes and returns the last value in an array.

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

pull (array, ...)

Aliases: remove.

Removes all provided values from a given array.

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

removeRange (array [, start = 1 [, finish = #array]])

Aliases: rmRange, M.chop.

Trims out all values index within a range.

local array = {1,2,3,4,5,6,7,8,9}
M.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(v, k, ...). Consecutive elements which return the same value are chunked together.

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

slice (array [, start = 1 [, finish = #array]])

Aliases: sub.

Slices and returns a part of an array.

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

first (array [, n = 1])

Aliases: head, M.take.

Returns the first N elements in an array.

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

initial (array [, n = #array])

Excludes the last N elements in an array.

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

last (array [, n = #array])

Returns the last N elements in an array.

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

rest (array [, index = 1])

Aliases: tail.

Returns all values after index, including the given index itself.

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

nth (array, index)

Returns the value at index.

local array = {1,2,3,4,5,6}
M.nth(array,3) -- => "3"

compact (array)

Trims out all falsy values.

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

flatten (array [, shallow = false])

Flattens a nested array.

M.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.

M.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}
M.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}
M.union(A,B,C) -- => "{'a',1,2,3,10}"

intersection (...)

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'}
M.intersection(A,B,C) -- => "{'a'}"

disjoint (...)

Checks if all passed in arrays are disjoint.

local A = {'a'}
local B = {'a',1,3}
local C = {3,10,2}

M.disjoint(A,B) -- => false
M.disjoint(A,C) -- => true
M.disjoint(B,C) -- => false

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}
M.symmetricDifference(array, array2) -- => "{2,3,4,5}"

unique (array)

Aliases: uniq.

Makes an array duplicate-free.

M.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.

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

duplicates (array)

Returns an array list of all duplicates in array.

M.duplicates({1,2,3,3,8,8,3,2,4}) -- => {2,3,8}

zip (...)

Aliases: transpose.

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

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

zipWith (f, ...)

Aliases: transposeWith.

Merges values using a given function. Only values indexed with the same key in the given arrays are merged in the same subset. Function f is used to combine values.

local names = {'Bob','Alice','James'}; local ages = {22, 23, 25}
local function introduce(name, age) return 'I am '..name..' and I am '..age..' years old.' end
local t = M.zipWith(introduce,names,ages)
-- => {
-- =>  'I am Bob and I am 22 years old.'
-- =>  'I am Alice and I am 23 years old.'
-- =>  'I am James and I am 25 years old.'
-- => }

append (array, other)

Appends two arrays.

M.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'}
M.interleave(t1, t2) -- => "{1,'a',2,'b',3,'c'}"

interpose (array, value)

Aliases: intersperce.

Interposes a value between consecutive values in an arrays.

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

range ([from [, to [, step]]])

Generates an arithmetic sequence.

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

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

M.range(3) -- => "{1,2,3}"

The incremental step can also be provided as third argument.

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

It also handles negative progressions.

M.range(-5) -- => "{-1,-2,-3,-4,-5}"
M.range(5,1) -- => "{5,4,3,2,1}"

rep (value, n)

Generates a list of n repetitions of a value.

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

powerset (array)

Returns the powerset of an array.

M.powerset {1,2,3} -- => "{{1},{2},{3},{1,2},{2,3},{1,2,3}}"

partition (array [, n = 1 [, pad]])

Aliases: part.

Returns an iterator function for partitions of a given array.

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

-- => 1,2
-- => 3,4
-- => 5,6

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

-- => 1,2,3,4
-- => 5,6

In case the last partition has less elements than desired, a 3rd argument can be supplied to adjust the partition size.

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

-- => 1,2,3,4
-- => 5,6,0,0

overlapping (array [, n = 2 [, pad]])

Returns an iterator function which provides overlapping subsequences of a given array.

local t = {1,2,3,4,5,6,7}
for p in M.overlapping(t,3) do
	print(table.concat(p,','))
end

-- => 1,2,3
-- => 3,4,5
-- => 5,6,7

for p in M.overlapping(t,4) do
	print(table.concat(p,','))
end

-- => 1,2,3,4
-- => 4,5,6,7

for p in M.overlapping(t,5) do
	print(table.concat(p,','))
end

-- => 1,2,3,4,5
-- => 5,6,7

In case the last subsequence wil not match the exact desired length, it can be adjusted with a 3rd argument pad.

local t = {1,2,3,4,5,6,7}
for p in M.overlapping(t,5,0) do
	print(table.concat(p,','))
end

-- => 1,2,3,4,5
-- => 5,6,7,0,0

aperture (array [, n = 2])

Aliases: sliding.

Returns an iterator function which provides sliding partitions of a given array.

local t = {1,2,3,4,5}
for p in M.aperture(t,4) do
  print(table.concat(p,','))
end

-- => 1,2,3,4
-- => 2,3,4,5

for p in M.aperture(t,3) do
  print(table.concat(p,','))
end

-- => 1,2,3
-- => 2,3,4
-- => 3,4,5

pairwise (array)

Iterator returning sliding pairs of an array.

local t = M.range(5)
for p in pairwise(t) do
  print(table.concat(p,','))
end

-- => 1,2
-- => 2,3
-- => 3,4
-- => 4,5

permutation (array)

Aliases: perm.

Returns an iterator function for permutations of a given array.

t = {'a','b','c'}
for p in M.permutation(t) do
  print(table.concat(p))
end

-- => 'bca'
-- => 'cba'
-- => 'cab'
-- => 'acb'
-- => 'bac'
-- => 'abc'

concat (array [, sep = '' [, i = 1 [, j = #array]]])

Aliases: join.

Concatenates a given array values:

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

xprod (array, array2)

Returns all possible pairs built from given arrays.

local t = M.xprod({1,2},{'a','b'})
-- => {{1,'a'},{1,'b'},{2,'a'},{2,'b'}}

xpairs (value, array)

Creates pairs from value and array. Value is always prepended to the pair.

local t = M.xpairs(1, {1, 2, 3})
-- => {{1,1},{1,2},{1,3}}

xpairsRight (value, array)

Creates pairs from value and array. Value is always appended as the last item to the pair.

local t = M.xpairsRight(1, {1, 2, 3})
-- => {{1,1},{2,1},{3,1}}

sum (array)

Returns the sum of array values.

M.sum({1,2,3,4,5}) -- => 15

product (array)

Returns the product of array values.

M.product({1,2,3,4,5}) -- => 120

mean (array)

Returns the mean of array values.

M.mean({1,2,3,4,5}) -- => 3

median (array)

Returns the median of array values.

M.median({1,2,3,4,5}) -- => 3
M.median({1,2,3,4}) -- => 2.5