7
\$\begingroup\$

I'm writing some table.tools to make table handling a little easier for me. But I'm a beginner with Lua, so you might help me a bit, to make the code better.

First of all I would like to get the best usability, but performance is a factor as well.

-- is compare equal to AT_LEASE one entry of list_to_search_in?
-- the idea was to make syntax like 
--" if value == var1 or value == var2 or value == var(n) "
--- a little shorter
function table.contains(list_to_search_in, compare)
 for k,v in pairs(list_to_search_in) do
 if compare == v then
 return true
 end
 end
 return false
end
 -- is compare equal to EVERY entry of list_to_search_in ?
function table.equalsAll(list_to_search_in, compare)
 local counter = 0
 local truth_counter = 0
 for k,v in pairs(list_to_search_in) do
 if compare == v then
 truth_counter = truth_counter + 1
 end
 counter = counter + 1
 end
 return (truth_counter == counter)
end
 -- compare is equal to HOW_MANY entrys of list_to_search_in?
 -- returns how many entrys are the same
function table.count(list_to_search_in, compare)
 local counter = 0
 for k,v in pairs(list_to_search_in) do
 if compare == v then
 counter = counter + 1
 end
 end
 return counter
end
 -- compare is equal to WHICH entrys of list_to_search_in?
 -- returns a map of equality
function table.truthmap(list_to_search_in, compare)
 local map = { }
 for k,v in pairs(list_to_search_in) do
 table.insert(map, { k , compare == v})
 end
 return map
end 
 -- deletes all entys in list, wich equals(or not[,invert]) to compare value
 -- returns a table with all entrys wich have not been equal
function table.removePerValue(list_to_search_in, compare, invert)
 local counter = 0
 local return_table = {}
 for k,v in pairs(list_to_search_in) do
 if invert and (v == compare) then 
 table.insert(return_table, v)
 elseif not invert and (v ~= compare) then
 table.insert(return_table, v)
 end
 end
 return return_table
end

(Feel free to use, I'm happy if the code helps someone)

asked Sep 9, 2014 at 12:06
\$\endgroup\$
2
  • \$\begingroup\$ Can you explain what removePerValue does? \$\endgroup\$ Commented Sep 11, 2014 at 12:53
  • \$\begingroup\$ returns a table that contains every entry of the given table, except every entry with the given value. example: table.remove({1,1,1,2,3,4,2}, 2) returns: {1,1,1,3,4} or: table.remove({1,1,1,2,3,4,2}, 2, true) returns: {2,2} \$\endgroup\$ Commented Sep 11, 2014 at 12:58

2 Answers 2

4
\$\begingroup\$
  • contains

    The function is fine.

  • equalsAll

    Since you are checking that all the items in table are the same, you can simply return false if any one of them does not match. The worst case scenario would be \$ O(n) \,ドル otherwise you'd get the check very quick.

    function table.equalsAll(list_to_search_in, compare)
     for k,v in pairs(list_to_search_in) do
     if compare ~= v then
     return false
     end
     end
     return true
    end
    
  • count

    The incrementing can be achieved in a single statement:

    counter = compare == v and counter + 1 or counter
    
  • truthmap

    The function is highly esoteric, and I'm unsure about its applications. Although, you can make your map to reflect the input table as follows:

    map[k] = compare == v
    
  • removePerValue

    I'd suggest adding a filtering callback.

The function would look like:

function table.filter( tInput, CallBack )
 local tFilter = {}
 for k, v in pairs(tInput) do
 if CallBack(v) then tFilter[k] = v end
 -- or table.insert( tFilter, v )
 -- as per your needs
 end
 return tFilter
end
function table.removePerValue(list_to_search_in, compare, invert)
 local fn = function(a) if invert then return compare == a else return compare ~= a end end
 return table.filter(list_to_search_in, fn)
end

And the usage will be like:

table.removePerValue({1,1,1,2,3,4,2}, 2, true) -- returns {[4]=2,[7]=2}
table.removePerValue({1,1,1,2,3,4,2}, 2) -- returns {1,1,1,[5]=3,[6]=4}

The filtering will allow you to encapsulate more features such as selecting values \$\geq\,ドル \$\leq\$ etc. only. Or some other complicated logical operations. A sample would be as follows:

table.filter({1,1,1,2,3,4,2}, function(a) return a >= 3 end) -- returns {[5]=3,[6]=4}
answered Sep 11, 2014 at 23:52
\$\endgroup\$
5
\$\begingroup\$

What is truthmap trying to achieve? I can't quite figure it out, sorry.

contains by nature will always be O(N) in your implementation, so yes, it's speed is equal to the number of elements in your table.

count should probably be renamed to countOf to better signify it's intent. Better yet, you could rename it where, have it take a function, and then allow the user to use the standard # operator on the resultant table.

removePerValue seems unnecessary with a where function. Users can simply filter the table rather than remove values from the table.

equalsAll in my opinion again should take a function as an argument and not an object.

You should change your loops from for k, v in pairs(tbl) do to for _, v in pairs(tbl) do if you are not using k.

I'm sure there's things to be said about the implementation of equalsAll but I don't have time to point that out at the moment.

Do you know about the # operator? appending # to the front of a table will return a value of the size of the table (more precisely, it will return the highest indexed number in the table, so it will be incorrect for sparse arrays).

You should ideally not need comments to explain the purpose of code - your functions should describe themselves ;-)

answered Sep 9, 2014 at 12:21
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.