How to get all values from array by using lua - lua

I have a multidimensional array:
result = {
{
data = {
language = "English",
name = "Freak Out",
list = {
{
type = "songs",
album = "1234"
}, {
type = "songs",
album = "4234"
}, {
type = "songs",
album = "5829"
}
}
}
}
}
How do I dynamically access the list in this array?
This code is printing first album (1234):
for i, v in pairs(result) do print(v.data.list[1].album) end
I want to print all albums with their type. How do I do this?

result is a list of tables
result[i].data.list is a list of tables.
for _, res in ipairs(result) do
for _, song in ipairs(res.data.list) do
print(song.type, song.album)
end
end
this outputs
songs 1234
songs 4234
songs 5829

First you need know table have two type in lua.One is hash table, and another is array.In your code. result's member and result.data is a hash table, every element have a string key.result and result.data.list is a array table, all the member in the table have the number key, the default index start by 1.
Second, to traverse the two type table, there are two functions, pairs for hash table and iparis for array table.
print all album in the list(array):
for k, v in ipairs(res.data.list) do
print(v.type, v.album)
end

Related

How do I get information from a table in lua?

I have some lua code like this:
_table = {
stuff = {
item1 = {Name="Stack",Rarity="Over"};
item2 = {Name="Flow",Rarity="Com"}
};
};
print("placeholder") -- example thing
_stuff = _table.stuff
for i = 1, #_stuff do
print(_stuff[i].Name)
end
The output is this:
placeholder
I've tried to look at stuff but I don't think it was related to my problem.
Lua tables conceptually are "maps": They map keys to values. Your table _table maps the key stuff to the {item1 = ..., item2 = ...} table. Your stuff table maps the string "item1" to the {Name="Stack",Rarity="Over"} table and the string "item2" to the {Name="Flow",Rarity="Com"} table.
The length operator # completely ignores string keys. It returns an integer i such that t[i] ~= nil and t[i+1] == nil. In particular, it returns 0 if there are no integer keys in the table. This is the case for your stuff table: You only have string keys. Thus your loop never runs, as the limit is 0 and i = 1 > 0 already is the case before the first loop iteration.
Put simply, you're trying to iterate over a "dictionary" (a table with string keys) as if it were a list. Lua tables have both a "list part" (integer keys from 1 to n, where usually n = #t) and a "hash part" (of all other keys). The "list part" is empty in your case, so there's nothing for you to iterate over.
To iterate over all key-value pairs of any table (list or dictionary) in an undefined order, use pairs (rather than ipairs or iterating over indices i, which only works for lists):
for itemname, item in pairs(_stuff) do
print(item.Name)
end
If you want a defined order of iteration, either build a second table of keys...
local order = {"item1", "item2"}
for _, key in ipairs(order) do
print(_stuff[key].Name)
end
... or use the integer keys ("list part") of the table:
_table = {
stuff = {
{key = "item1", Name="Stack", Rarity="Over"};
{key = "item2", Name="Flow", Rarity="Com"};
};
};
_stuff = _table.stuff
for _, key in ipairs(order) do
for i = 1, #_stuff do
print(_stuff[i].Name)
end
end
then works as expected.

Lua: Passing index of nested tables as function arguments?

Is it possible to have a function that can access arbitrarily nested entries of a table?
The following example is just for one table. But in my real application I need the function to check several different tables for the given (nested) index.
local table1 = {
value1 = "test1",
subtable1 = {
subvalue1 = "subvalue1",
},
}
local function myAccess(index)
return table1[index]
end
-- This is fine:
print (myAccess("value1"))
-- But how do I access subtable1.subvalue1?
print (myAccess("subtable1.subvalue1???"))
You won't be able to do this using a string unless you use load to treat it as Lua code or make a function to walk on a table.
You can make a function which will split your string by . to get each key and then go one by one.
You can do this using gmatch + one local above gmatch with current table.
#Spar: Is this what you were suggesting? It works anyway, so thanks!
local table1 = {
value1 = "test1",
subtable1 = {
subvalue1 = "subvalue1",
},
}
local function myAccess(index)
local returnValue = table1
for key in string.gmatch(index, "[^.]+") do
if returnValue[key] then
returnValue = returnValue[key]
else
return nil
end
end
return returnValue
end
-- This is fine:
print (myAccess("value1"))
-- So is this:
print (myAccess("subtable1.subvalue1"))

How can i keep this table in the shown order?

Hello i have got a table, that uses string indexes:
shirt = {
["shirtwhite.png"] = "shirt_white.png",
["shirtwhite.png^[multiply:#3f3f3f"] = "shirt_white.png^[multiply:#3f3f3f",
["shirtwhite.png^[multiply:#ff0000"] = "shirt_white.png^[multiply:#ff0000",
["shirtwhite.png^[multiply:#ff7f00"] = "shirt_white.png^[multiply:#ff7f00",
["shirtwhite.png^[multiply:#ffff00"] = "shirt_white.png^[multiply:#ffff00",
["shirtwhite.png^[multiply:#00ff00"] = "shirt_white.png^[multiply:#00ff00",
["shirtwhite.png^[multiply:#0000ff"] = "shirt_white.png^[multiply:#0000ff",
["shirtwhite.png^[multiply:#9f00ff"] = "shirt_white.png^[multiply:#9f00ff",
},
Theese are t-shirt-textures for an editable game-character-skin (with colour-values for different colors).
There are some more of theese tables in the code, for other parts of the character-skin
how can I keep the table in it´s shown order, while it´s loaded in this code-snippet?
The tzables are in a file "skins.lua" and the code-snippet is from another lua-file
character_creator = {}
character_creator.skins = dofile(minetest.get_modpath("character_creator") .. "/skins.lua")
local skins = character_creator.skins
local skins_array = {}
minetest.after(0, function()
local function associative_to_array(associative)
local array = {}
for key in pairs(associative) do
table.insert(array, key)
end
return array
end
skins_array = {
skin = associative_to_array(skins.skin),
hair = associative_to_array(skins.hair),
eyes = associative_to_array(skins.eyes),
shirt = associative_to_array(skins.shirt),
pants = associative_to_array(skins.pants),
}
end)
In Lua only arrays (positive integer-indexed tables) have "order" (can be iterated using ipairs); the hash tables (like the one you are working with) are unordered. If you want to iterate over a table like this in a specific order, you'd usually create an array with the keys, sorted them in the order you want and then iterate over that array extracting elements from your table.
There are also components (like ordered table) that may keep track of insertions and return results in the same order, if that's what you want.

groovy&grails- How to go over array of object?

I have an array of Person object (person.first person.last).
To find out if the person have first name I have to "run" on the array.
I try the following but I got error:
person.eachWithIndex { String persons, i ->
if(persons.first=='')
println(''error)
}
How should I manipulate the object array?
Are you looking for something like:
class Person {
def first
def last
}
def persons = [ new Person(first:'',last:'last'), new Person(first:'john',last:'anon')]
persons.eachWithIndex { person, i ->
if(person.first==''){
println("error at person in position $i")
}
}
Since you doesn't add more details, I don't know what you're looking for when you say manipulate object array so there is some samples:
To manipulate the array objects you can add the statements in the each itself, for example to add a notDefined as a first for person where first=='' you can use:
persons.eachWithIndex { person, i ->
if(person.first==''){
person.first = 'notDefined'
println("first as notDefined for person in position $i")
}
}
To remove the elements where first =='' you can use removeAll method to remove the undesired elements from the array:
persons.removeAll { person ->
!person.first
}
EDIT BASED ON COMMENT:
If you want to remove null elements from your list, you can do it with the expression you use in your comment:
def persons = [ new Person(first:'pepe',last:'last'), null]
persons.removeAll([null])
println persons.size() // prints 1 since null element is removed
However seems that you're not trying to remove null elements instead you're trying to remove elements where all the properties are null, in your case you want to remove: new Person(first:null,last:null). To do so you can try with the follow code:
def persons = [ new Person(first:'pepe',last:'last'), new Person(first:null,last:null)]
persons.removeAll{ person ->
// get all Person properties wich value is not null
// without considering class propertie wich is implicit in all classes
def propsNotNull = person.properties.findAll { k,v -> v != null && k != 'class' }
// if list is empty... means that all properties are null
return propsNotNull.isEmpty()
}
println persons.size() // prints 1
Hope this helps,

How to quickly initialise an associative table in Lua?

In Lua, you can create a table the following way :
local t = { 1, 2, 3, 4, 5 }
However, I want to create an associative table, I have to do it the following way :
local t = {}
t['foo'] = 1
t['bar'] = 2
The following gives an error :
local t = { 'foo' = 1, 'bar' = 2 }
Is there a way to do it similarly to my first code snippet ?
The correct way to write this is either
local t = { foo = 1, bar = 2}
Or, if the keys in your table are not legal identifiers:
local t = { ["one key"] = 1, ["another key"] = 2}
i belive it works a bit better and understandable if you look at it like this
local tablename = {["key"]="value",
["key1"]="value",
...}
finding a result with : tablename.key=value
Tables as dictionaries
Tables can also be used to store information which is not indexed
numerically, or sequentially, as with arrays. These storage types are
sometimes called dictionaries, associative arrays, hashes, or mapping
types. We'll use the term dictionary where an element pair has a key
and a value. The key is used to set and retrieve a value associated
with it. Note that just like arrays we can use the table[key] = value
format to insert elements into the table. A key need not be a number,
it can be a string, or for that matter, nearly any other Lua object
(except for nil or 0/0). Let's construct a table with some key-value
pairs in it:
> t = { apple="green", orange="orange", banana="yellow" }
> for k,v in pairs(t) do print(k,v) end
apple green
orange orange
banana yellow
from : http://lua-users.org/wiki/TablesTutorial
To initialize associative array which has string keys matched by string values, you should use
local petFamilies = {["Bat"]="Cunning",["Bear"]="Tenacity"};
but not
local petFamilies = {["Bat"]=["Cunning"],["Bear"]=["Tenacity"]};

Resources