[Home] [Downloads] [Search] [Help/forum]

Gammon Forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Lua
. . -> [Subject]  Constructing a table using values from another table.
Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

Constructing a table using values from another table.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Posted by Bobble   Canada  (76 posts)  [Biography] bio
Date Thu 27 Nov 2008 03:12 AM (UTC)

Amended on Thu 27 Nov 2008 03:13 AM (UTC) by Bobble

Message
Greets everyone,

I'm encountering a problem that I'm sure has a simple solutions, but I'm just missing it.

I have a table used for another purpose, but would like to use the information in that table to construct a different table.

This original table looks like this:


characters = {
     {name = "jim"     ,race = "dwarf"     ,class = "priest"}
     {name = "john"    ,race = "dwarf"     ,class = "warrior"}
     {name = "ben"     ,race = "human"     ,class = "priest}
     {name = "lynn"    ,race = "elf"       ,class = "warrior"}
     {name = "terry"   ,race = "elf"       ,class = "warrior"}
}


What I want to do is make a function that uses this table to create a new table where the keys are the races and the values are the names of people that belong to that race.

Thus one of the key value pairings in this new table would be:

dwarf = "jim, john"
etc.

I tried doing this:


for _, v in ipairs(characters) do
	race_index [v.race] = v.name
end


Of course, the problem with this is that instead of adding the name to the value of the race key, it's overwriting the value.

Any ideas on how to get each name added to the respective race key?

Please let me know if I need to clarify anything or further information is required.

Open the watch.
[Go to top] top

Posted by WillFa   USA  (525 posts)  [Biography] bio
Date Reply #1 on Thu 27 Nov 2008 03:31 AM (UTC)
Message
for _, v in ipairs(characters) do
	race_index [v.race] = race_index [v.race] or {}
        race_index [v.race][#race_index [v.race] + 1] = v.name
end


Would be the easiest way. It essentially makes:

race_index = { dwarf = {"jim" , "john" } ,
               human = { "ben" } ,
               elf   = { "lynn", "terry" }
             }

# is the length operator. For tables it returns the highest contiguous index in the table. (i.e. in a table that's t = {1,2,3, [5] = 5, foo = "bar", sample = "contrived"} - #t is 3, the highest sequential index; not 5 the highest ordinal, or 6 the number of elements in the table) so "t[#t + 1]" is how you append to the end of a table in Lua.


If having nested tables isn't to your liking, after populating the tables you can use

Race_Index = {}
for r,t in pairs(race_index) do
 Race_Index[r] = table.concat(t , ", ")
end

to get the dwarf = "jim, john" formatting.

[Go to top] top

Posted by Worstje   Netherlands  (899 posts)  [Biography] bio
Date Reply #2 on Thu 27 Nov 2008 03:35 AM (UTC)

Amended on Thu 27 Nov 2008 01:01 PM (UTC) by Worstje

Message
Easiest would be to do something like:


for _, v in ipairs(characters) do
  -- Make sure table entry exists.
  race_index [v.race] = race_index [v.race] or {}
  table.insert(race_index [v.race], v.name)
end

-- To display in the format you gave...

-- Taken from: http://lua-users.org/wiki/SplitJoin
-- Concat the contents of the parameter list,
-- separated by the string delimiter (just like in perl)
-- example: strjoin(", ", {"Anna", "Bob", "Charlie", "Dolores"})
function strjoin(delimiter, list)
  local len = getn(list)
  if len == 0 then 
    return "" 
  end
  local string = list[1]
  for i = 2, len do 
    string = string .. delimiter .. list[i] 
  end
  return string
end

-- here it comes:

Note(strjoin(", ", race_index [v.race]))



It might seem a bit difficult or long, but this way you get to use the values for other purposes than displaying too (and add/remove or whatever). Your original approach didn't work because the key is unique (hence it being called a key).

A shorter variety could also be made in one line: Just append (", "..v.name) every time, and do a string.sub() at the end which removes the first few characters. But again, that is only a useful approach if you do not need the names or information for other purposes.


Edited: Fixed. Thanks Nick, it was the last thing I wrote before hitting the pillow. :)
[Go to top] top

Posted by Nick Gammon   Australia  (21,323 posts)  [Biography] bio   Forum Administrator
Date Reply #3 on Thu 27 Nov 2008 07:24 AM (UTC)
Message
You need to "escape forum codes" Worstje - your [i] has turned the second half of your post into italics.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Bobble   Canada  (76 posts)  [Biography] bio
Date Reply #4 on Thu 27 Nov 2008 12:22 PM (UTC)
Message
Thanks to both of you! I got exactly what I needed.

Open the watch.
[Go to top] top

Posted by WillFa   USA  (525 posts)  [Biography] bio
Date Reply #5 on Thu 27 Nov 2008 02:39 PM (UTC)
Message
Hey Worstje, what's the difference between the StrJoin function you wrote and the table.concat() function?

Seems like they accomplish the same thing.
[Go to top] top

Posted by Worstje   Netherlands  (899 posts)  [Biography] bio
Date Reply #6 on Thu 27 Nov 2008 04:51 PM (UTC)
Message
I didn't write it. I took it from the wiki-page I referenced.

And why I don't use table.concat... well, it's a good question. I always think of said operation as a join(), and unless I read over it said wiki page doesn't reference table.concat() either. And I just searched the document.. it's all the way on the bottom, inbetween version specific stuff near the footer. Gah! :/

Besides that, I end up reinventing the wheel in Lua often enough that I don't question those pages anymore. If I see a page dedicated to the exact topic I need, and it doesn't reference a builtin function, I've become used to just accepting Lua doesn't have a builtin for it and that I need to use some snippet for it.

On that sidenote.. this function is still a nice template for when you need to merge members of tables, which cannot be done with table.concat. :)
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


5,230 views.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at FutureQuest]