Mini Functions Repository

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Mini Functions Repository

Post by Positive07 »

HugoBDesigner wrote:I wrote a simple array organizer for numerical entries. I know these things come with Lua already, but after I wrote one for strings (long ago, dunno where to find it), I figured I'd give numbers a try:
Mmm sorry but wouldn't [manual]table.sort[/manual] work?
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Mini Functions Repository

Post by HugoBDesigner »

Yeah, it would, but it was mostly experimental. I already knew of table.sort, but figured I'd give it a try to see how it'd work.
Speaking of that, I finally found the alphabetical organizer: it was in my Minigame Simulator all along :D

Code: Select all

function alphabetic_order(a, b)
	local g = "abcdefghijklmnopqrstuvwxyz"
	local alphabet = {}
	for i = 1, string.len(g) do table.insert(alphabet, string.sub(g, i, i)) end
	
	local a, b = string.lower(a), string.lower(b)
	for j = 1, math.min(string.len(a), string.len(b)) do
		local aa, bb = string.sub(a, j, j), string.sub(b, j, j)
		if aa ~= bb then
			if table.contains(alphabet, aa) and table.contains(alphabet, bb) then
				if table.contains(alphabet, aa) < table.contains(alphabet, bb) then
					return true
				elseif table.contains(alphabet, aa) > table.contains(alphabet, bb) then
					return false
				end
			elseif table.contains(alphabet, aa) then
				return false
			else
				return true
			end
		elseif j == math.min(string.len(a), string.len(b)) then --virtually similar, return the smallest as first
			return (string.len(a) < string.len(b) and true) or false
		end
	end
end
And to use it:

Code: Select all

table.sort(table, function(a, b)
	return alphabetic_order(table[a], table[b])
end)
@HugoBDesigner - Twitter
HugoBDesigner - Blog
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Mini Functions Repository

Post by Positive07 »

You can take this part out of the function since it is constant:

Code: Select all

   local g = "abcdefghijklmnopqrstuvwxyz"
   local alphabet = {}
   for i = 1, string.len(g) do table.insert(alphabet, string.sub(g, i, i)) end
Then again, you can compare two strings in Lua with > and < and they sort alphabetically, not sure about caps but you can always do

Code: Select all

table.sort(t, function (a, b)
	return string.lower(a) < string.lower(b)
end)
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Mini Functions Repository

Post by davisdude »

How 'bout this? :cool:

Code: Select all

function alphabetic_sort(a,b)
    -- Handle words that are the same until a certain point
    local i = 1
    while a:sub( i, i ) == b:sub( i, i ) do
        i = i + 1
        -- No letter goes before words with letters
        if i > #a then return true end
        if i > #b then return false end
    end
    return a:sub( i, i ) < b:sub( i, i )
end
Use it in the same way:

Code: Select all

table.sort( tab, alphabetic_sort )
-- Reverse alphabetized
table.sort( tab, function( a, b ) return not alphabetic_sort( a, b ) end )
Plus, it doesn't rely on table.contains

*edit: Thanks to Positive07 for teaching me you can compare strings with '<' and '>'!
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Mini Functions Repository

Post by Positive07 »

I'm pretty sure you can do that just with table.sort:

Code: Select all

local t = {
    "something",
    "somewhere",
    "someone",
    "someday",
    "some",
    "so",
    "s",
    "abc"
}

table.sort(t)

for i, v in ipairs(t) do
   print(i, v)
end

--Output:
--1	abc
--2	s
--3	so
--4	some
--5	someday
--6	someone
--7	something
--8	somewhere
Note, uppercase are sorted first and then lower case, that is "S" is lower than "s" so if you need to ignore case then use the code I posted before:

Code: Select all

table.sort(t, function (a,b) return string.lower(a) < string.lower(b) end)
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Mini Functions Repository

Post by zorg »

String sorting probably follows the underlying encoding's numerical values, and since the first 127 should be somewhat standard across all "ansi" codepages (or, if you want me to be utterly explicit, will be equivalent to ISO/IEC_8859-1 and/or Windows-1252), the order of 0-9A-Za-z will be adhered to. Don't quote me on this though. :3
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Mini Functions Repository

Post by Positive07 »

I quote you on that, that is how it works, and it does it on a character by character basics, so if the first is equal it goes with the next one and so on...
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
pgimeno
Party member
Posts: 3674
Joined: Sun Oct 18, 2015 2:58 pm

Re: Mini Functions Repository

Post by pgimeno »

Here's a pair of functions that allow storing tuples into tables and then retrieving back these tables as tuples:

Code: Select all

local function pack_n(...)
  return {select('#', ...), ...}
end

local unpack_n
do
  local function unpack_count(x, n)
    if n == x[1] + 1 then
      return
    end
    n = n + 1
    return x[n], unpack_count(x, n)
  end

  function unpack_n(a)
    return unpack_count(a, 1)
  end
end
Example usage:

Code: Select all

local function my_crazy_func()
  return nil, 2, 3, nil, "yes", math.acos(3), false, nil
end

-- Store the returned tuple in a table
local packed = pack_n(my_crazy_func())
-- Retrieve the table as a tuple and print it
print(unpack_n(packed))
-- output: nil	2	3	nil	yes	nan	false	nil

-- By comparison, using the default Lua unpack fails with the nils:
packed = {my_crazy_func()}
print(unpack(packed))
-- output: nil 2 3
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: Mini Functions Repository

Post by ReFreezed »

pgimeno wrote: Mon Mar 02, 2020 10:44 am Here's a pair of functions that allow storing tuples into tables and then retrieving back these tables as tuples:
Lua 5.2 adds a similar "pack" function to the standard table module that's implemented like this:

Code: Select all

local function pack(...)
	return {n=select("#", ...), ...}
end
local function getSomeValues()
	return 8, nil, "foo"
end
local packed = pack(getSomeValues())
print(unpack(packed, 1, packed.n)) -- 8 nil foo
I wanna say it's a more "standard" way of storing and using tuples (not that it really matters for such a simple little thing ^^ ).
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 2 guests