├── .gitignore ├── LICENSE ├── README ├── lua-enumerable.lua └── test-lua-enumerable.lua /.gitignore: -------------------------------------------------------------------------------- 1 | lunit 2 | lunit-console.lua 3 | lunit-tests.lua 4 | lunit.lua 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | Copyright (c) 2011 Michael Judge 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | 11 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | lua-enumerable is a quick and dirty port of the ruby Enumerable library plus some extras. 2 | 3 | It's a native lua library. Installation is as simple as dropping lua-enumerable.lua in 4 | your project and requiring it: 5 | 6 | require("lua-enumerable") 7 | 8 | Synopsis: 9 | 10 | local test = {1,2,3} 11 | 12 | table.each(test, function (x) print(x) end) 13 | -- 1 14 | -- 2 15 | -- 3 16 | 17 | local holes = {1,2,7} 18 | table.each(holes, function(x) print(x) end) 19 | -- 1 2 7 20 | table.every(holes, function(x) print(x) end) 21 | -- 1 2 7 22 | holes["1"] = "one" 23 | holes["2"] = "two" 24 | holes["7"] = "seven" 25 | table.every(holes, function(x) print(x) end) 26 | -- 1 2 7 one seven two 27 | --BUT! 28 | table.each(holes, function(x) print(x) end) 29 | --1 2 7 30 | 31 | table.collect(test, function (x) return x + 1 end) 32 | -- {2, 3, 4} 33 | 34 | table.select(test, function (x) return x < 3 end) 35 | -- {1, 2} 36 | 37 | table.reject(test, function (x) return x < 3 end) 38 | -- {3} 39 | 40 | table.without(test, 3) 41 | -- {1, 2} 42 | 43 | table.partition(test, function (x) return x < 3 end) 44 | -- {1, 2}, {3} 45 | 46 | table.includes(test, 3) 47 | -- true 48 | 49 | table.detect(test, function (x) return x == 3 end) 50 | -- 3 51 | 52 | table.detect(test, function (x) return x == 4 end) 53 | -- nil 54 | 55 | table.merge({a=1, b=2}, {c=3}) 56 | -- {a=1, b=2, c=3} 57 | -- Note: modifies the first table 58 | 59 | table.times(4, function (x) print(x) end) 60 | -- 1 61 | -- 2 62 | -- 3 63 | -- 4 64 | 65 | table.keys({a=1,b=2,c=3}) 66 | -- {"a", "c", "b"} 67 | 68 | Provides some array manipulation functions: 69 | 70 | table.pop(test) 71 | -- 3 72 | -- Note: modifies the input array {1,2} 73 | 74 | table.shift(test) 75 | -- 1 76 | -- Note: modifies the input array {2,3} 77 | 78 | table.unshift(test, 4) 79 | -- {4, 1, 2, 3} 80 | -- Note: modifies the input array 81 | 82 | table.push(test, 4) 83 | -- {1, 2, 3, 4} 84 | -- Note: modifies the input array 85 | 86 | table.reverse({1,2,3}) 87 | -- {3,2,1} 88 | 89 | Random elements: 90 | 91 | table.random(test) 92 | -- {3} 93 | 94 | table.shuffle(test) 95 | -- {3,2,1} 96 | -- Note: modifies the input table 97 | 98 | Boolean tests for sexy if statements: 99 | 100 | table.empty({}) 101 | -- true 102 | 103 | table.empty(nil) 104 | -- true 105 | 106 | table.empty({1,2,3}) 107 | -- false 108 | 109 | table.present({}) 110 | -- false 111 | 112 | table.present(nil) 113 | -- false 114 | 115 | table.present({1,2,3}) 116 | -- true 117 | 118 | Misc: 119 | 120 | table.dup({1,2,3}) 121 | -- {1,2,3} 122 | 123 | 124 | If you've got any useful functions or suggestions, send it to me via a pull request, 125 | email (mikelovesrobots@gmail.com) or paste into an issue here in github. (The transmission 126 | method doesn't really matter. What matters is that you're being awesome.) 127 | 128 | Thanks for checking out my humble little library. 129 | 130 | -------------------------------------------------------------------------------- /lua-enumerable.lua: -------------------------------------------------------------------------------- 1 | table.includes = function(list, value) 2 | for i,x in ipairs(list) do 3 | if (x == value) then 4 | return(true) 5 | end 6 | end 7 | return(false) 8 | end 9 | 10 | table.detect = function(list, func) 11 | for i,x in ipairs(list) do 12 | if (func(x, i)) then 13 | return(x) 14 | end 15 | end 16 | return(nil) 17 | end 18 | 19 | table.without = function(list, item) 20 | return table.reject(list, function (x) 21 | return x == item 22 | end) 23 | end 24 | 25 | table.each = function(list, func) 26 | for i,v in ipairs(list) do 27 | func(v, i) 28 | end 29 | end 30 | 31 | table.every = function(list, func) 32 | for i,v in pairs(list) do 33 | func(v, i) 34 | end 35 | end 36 | 37 | table.select = function(list, func) 38 | local results = {} 39 | for i,x in ipairs(list) do 40 | if (func(x, i)) then 41 | table.insert(results, x) 42 | end 43 | end 44 | return(results) 45 | end 46 | 47 | table.reject = function(list, func) 48 | local results = {} 49 | for i,x in ipairs(list) do 50 | if (func(x, i) == false) then 51 | table.insert(results, x) 52 | end 53 | end 54 | return(results) 55 | end 56 | 57 | table.partition = function(list, func) 58 | local matches = {} 59 | local rejects = {} 60 | 61 | for i,x in ipairs(list) do 62 | if (func(x, i)) then 63 | table.insert(matches, x) 64 | else 65 | table.insert(rejects, x) 66 | end 67 | end 68 | 69 | return matches, rejects 70 | end 71 | 72 | table.merge = function(source, destination) 73 | for k,v in pairs(destination) do source[k] = v end 74 | return source 75 | end 76 | 77 | table.unshift = function(list, val) 78 | table.insert(list, 1, val) 79 | end 80 | 81 | table.shift = function(list) 82 | return table.remove(list, 1) 83 | end 84 | 85 | table.pop = function(list) 86 | return table.remove(list) 87 | end 88 | 89 | table.push = function(list, item) 90 | return table.insert(list, item) 91 | end 92 | 93 | table.collect = function(source, func) 94 | local result = {} 95 | for i,v in ipairs(source) do table.insert(result, func(v)) end 96 | return result 97 | end 98 | 99 | table.empty = function(source) 100 | return source == nil or next(source) == nil 101 | end 102 | 103 | table.present = function(source) 104 | return not(table.empty(source)) 105 | end 106 | 107 | table.random = function(source) 108 | return source[math.random(1, #source)] 109 | end 110 | 111 | table.times = function(limit, func) 112 | for i = 1, limit do 113 | func(i) 114 | end 115 | end 116 | 117 | table.reverse = function(source) 118 | local result = {} 119 | for i,v in ipairs(source) do table.unshift(result, v) end 120 | return result 121 | end 122 | 123 | table.dup = function(source) 124 | local result = {} 125 | for k,v in pairs(source) do result[k] = v end 126 | return result 127 | end 128 | 129 | -- fisher-yates shuffle 130 | function table.shuffle(t) 131 | local n = #t 132 | while n > 2 do 133 | local k = math.random(n) 134 | t[n], t[k] = t[k], t[n] 135 | n = n - 1 136 | end 137 | return t 138 | end 139 | 140 | table.keys = function(source) 141 | local result = {} 142 | for k,v in pairs(source) do 143 | table.push(result, k) 144 | end 145 | return result 146 | end 147 | -------------------------------------------------------------------------------- /test-lua-enumerable.lua: -------------------------------------------------------------------------------- 1 | require "lunit" 2 | require "lua-enumerable" 3 | 4 | module( "test-lua-enumerable", lunit.testcase, package.seeall ) 5 | 6 | function test_every() 7 | y = 0 8 | table.every({1,2,nil,7}, function (x) y = y + x end) 9 | assert_equal(y, 10) 10 | end 11 | 12 | function test_each() 13 | y = 0 14 | table.each({1,2,3}, function (x) y = y + x end) 15 | assert_equal(y, 6) 16 | end 17 | 18 | function test_times() 19 | y = 0 20 | table.times(3, function (x) y = y + x end) 21 | assert_equal(y, 6) 22 | end 23 | 24 | function test_collect() 25 | local result = table.collect({1,2,3}, function (x) return x + 1 end) 26 | 27 | assert_equal(2, result[1]) 28 | assert_equal(3, result[2]) 29 | assert_equal(4, result[3]) 30 | end 31 | 32 | function test_select() 33 | local result = table.select({1,2,3}, function (x) return x < 3 end) 34 | 35 | assert_equal(2, #result) 36 | assert_equal(1, result[1]) 37 | assert_equal(2, result[2]) 38 | end 39 | 40 | function test_reject() 41 | local result = table.reject({1,2,3}, function (x) return x < 3 end) 42 | 43 | assert_equal(1, #result) 44 | assert_equal(3, result[1]) 45 | end 46 | 47 | function test_partition() 48 | local matches, rejects = table.partition({1,2,3}, function (x) return x < 3 end) 49 | 50 | assert_equal(2, #matches) 51 | assert_equal(1, matches[1]) 52 | assert_equal(2, matches[2]) 53 | 54 | assert_equal(1, #rejects) 55 | assert_equal(3, rejects[1]) 56 | end 57 | 58 | function test_includes() 59 | local a = {1,2,3} 60 | 61 | assert_true(table.includes(a, 3)) 62 | assert_false(table.includes(a, 4)) 63 | end 64 | 65 | function test_detect() 66 | local test = {1, 2, 3} 67 | 68 | assert_equal(3, table.detect(test, function (x) return x == 3 end)) 69 | assert_equal(nil, table.detect(test, function (x) return x == 4 end)) 70 | end 71 | 72 | function test_merge() 73 | local test = {a=1,b=2} 74 | table.merge(test, {c=3}) 75 | 76 | assert_equal(1, test.a) 77 | assert_equal(2, test.b) 78 | assert_equal(3, test.c) 79 | end 80 | 81 | function test_pop() 82 | local test = {1,2} 83 | local result = table.pop(test) 84 | 85 | assert_equal(2, result) 86 | 87 | assert_equal(1, #test) 88 | assert_equal(1, test[1]) 89 | end 90 | 91 | function test_shift() 92 | local test = {1,2} 93 | local result = table.shift(test) 94 | 95 | assert_equal(1, result) 96 | 97 | assert_equal(1, #test) 98 | assert_equal(2, test[1]) 99 | end 100 | 101 | function test_unshift() 102 | local test = {1,2} 103 | table.unshift(test, 3) 104 | 105 | assert_equal(3, #test) 106 | assert_equal(3, test[1]) 107 | assert_equal(1, test[2]) 108 | assert_equal(2, test[3]) 109 | end 110 | 111 | function test_push() 112 | local test = {1,2} 113 | table.push(test, 3) 114 | 115 | assert_equal(3, #test) 116 | assert_equal(1, test[1]) 117 | assert_equal(2, test[2]) 118 | assert_equal(3, test[3]) 119 | end 120 | 121 | function test_empty() 122 | assert_true(table.empty({})) 123 | assert_true(table.empty(nil)) 124 | assert_false(table.empty({1})) 125 | end 126 | 127 | function test_present() 128 | assert_false(table.present({})) 129 | assert_false(table.present(nil)) 130 | assert_true(table.present({1})) 131 | end 132 | 133 | function test_reverse() 134 | local result = table.reverse({1,2,3}) 135 | assert_equal(3, #result) 136 | assert_equal(3, result[1]) 137 | assert_equal(2, result[2]) 138 | assert_equal(1, result[3]) 139 | end 140 | 141 | function test_dup() 142 | local result = table.dup({a=1, b=2, c=3}) 143 | 144 | assert_equal(1, result.a) 145 | assert_equal(2, result.b) 146 | assert_equal(3, result.c) 147 | end 148 | 149 | function test_shuffle() 150 | math.randomseed(1234567890) 151 | local result = table.shuffle({1,2,3}) 152 | 153 | assert_equal(3, result[1]) 154 | assert_equal(2, result[2]) 155 | assert_equal(1, result[3]) 156 | end 157 | 158 | function test_keys() 159 | local result = table.keys({a=1, b=2, c=3}) 160 | assert_equal('a', result[1]) 161 | assert_equal('c', result[2]) 162 | assert_equal('b', result[3]) 163 | assert_equal(3, #result) 164 | end --------------------------------------------------------------------------------