WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Checking a value against every value in a table (https://www.wowinterface.com/forums/showthread.php?t=45872)

Clamsoda 02-23-13 07:26 AM

Checking a value against every value in a table
 
Back with another LUA question:

I am interested if LUA inherently supports checking a value against ANY value in a table. Let me explain.

Let us say we have a table with some values:

Lua Code:
  1. local myTable = {
  2.     "Value1",
  3.     "Value2",
  4.     "Value3"
  5. }

Is there any way I can check some variable against the whole table as in:

Lua Code:
  1. if some variable == ANY value in myTable then code here end

I am curious because using a
Lua Code:
  1. for k, v in pairs(myTable)
loop seems a bit bulky just to decide if the variable matches any value in said table.

Thank you for your time and assistance!

Haleth 02-23-13 08:01 AM

Your table is an indexed table; every value is automatically assigned an index number. Any kind of 'contains' function will use either a loop or a search algorithm to find the correct value.

If you set it up like this:

Code:

local myTable = {
    ["Value1"] = true,
    ["Value2"] = true,
    ["Value3"] = true,
}

Then you have a key-value table where your previous values serve as keys and the value is always true, so you can perform a lookup like this:

Code:

if myTable[someVariable] then ...

Clamsoda 02-23-13 08:33 AM

Well, perhaps I should delve a bit deeper into what I am striving for. Let us say that I have an input that may have ANY value. I want to check this against a table of any possible value that may be considered valid. Let me set up a few examples:

local input = "Haleth"

local table = {
"Phanx",
"Clamsoda",
"Seerah",
"Dridzt",
"Haleth"
}

What I would like to do is construct an IF statement that if the input is ever ANY value that is in said table, that we may proceed with the code. And this process will remain true for any amount of values I add to, or remove from the table, and is independent of the input value. The input may become "apple", or "seven", in which case it wouldn't match, unless "apple" or "seven" was added to the table. Additionally, if I removed "Haleth" from the table the input would no longer be true.

I am very sorry if I missed your point, or not illustrating mine correctly.

semlar 02-23-13 08:45 AM

Haleth's example is how you do this unless you have some reason not to just use the value you're looking up as the key, like if the values aren't unique, and even then if the table is large enough you might consider constructing a lookup table.

Clamsoda 02-23-13 08:50 AM

Ahh, I do believe that I read Haleth's post too quickly, and this his solution will be perfect. I have been up and at this for....some time, so excuse the mistake.

Thank you much for the input!

Edit: Working perfectly, thank you for your input Haleth, and for making me re-read it Semlar.

Dridzt 02-23-13 12:30 PM

I understand that you solved your problem by altering your table from an array style table to a hash style table.

However for others that might stumble on this thread I'll add that Blizz has implemented a global function in UIParent that allows checking for the existence of a value in an array style table.
Code:

local exists = tContains(table, value)
checks if table contains value, table being of type {[1]=value1, [2]=value2,...,[n]=valuen} or {value1, value2,..., valuen}

Seerah 02-23-13 12:49 PM

Wouldn't this just be a wrapper for the pairs() loop?

Haleth 02-23-13 01:03 PM

The tContains function is implemented like this:

Code:

function tContains(table, item)
      local index = 1;
      while table[index] do
              if ( item == table[index] ) then
                      return 1;
              end
              index = index + 1;
      end
      return nil;
end

So yes, it also uses a loop.

Seerah 02-23-13 01:08 PM

*nod*

But thanks for that, Dridzt. It's useful if you don't want to (or can't) change your table structure and would rather use the wrapper function.

Xinhuan 03-04-13 09:52 PM

Quote:

Originally Posted by Clamsoda (Post 273348)
Well, perhaps I should delve a bit deeper into what I am striving for. Let us say that I have an input that may have ANY value. I want to check this against a table of any possible value that may be considered valid. Let me set up a few examples:

local input = "Haleth"

local table = {
"Phanx",
"Clamsoda",
"Seerah",
"Dridzt",
"Haleth"
}

What I would like to do is construct an IF statement that if the input is ever ANY value that is in said table, that we may proceed with the code. And this process will remain true for any amount of values I add to, or remove from the table, and is independent of the input value. The input may become "apple", or "seven", in which case it wouldn't match, unless "apple" or "seven" was added to the table. Additionally, if I removed "Haleth" from the table the input would no longer be true.

I am very sorry if I missed your point, or not illustrating mine correctly.

You could restructure your table to:

local table = {
"Phanx" = 1,
"Clamsoda" = 1,
"Seerah" = 1,
"Dridzt" = 1,
"Haleth" = 1
}

If you add Phanx to the table, you would do
table["Phanx"] = (table["Phanx"] or 0) + 1

Checking if it exists is just

if (table["Phanx"]) then ...

The key is the string, and the value is the number of times it is added to the table. This method would obviously not work if you need the table to be sorted in a particular order instead.

Phanx 03-05-13 12:22 AM

Yes, but your syntax is bad, Xin. You must be rusty from all that time away!

This works:
Code:

local tbl = {
    ["Phanx"] = 1,
    ["Clamsoda"] = 1,
    ["Seerah"] = 1,
    ["Dridzt"] = 1,
    ["Haleth"] = 1,
}

And this works, for strings containing only letters, numbers, and underscores:
Code:

local tbl = {
    Phanx = 1,
    Clamsoda = 1,
    Seerah = 1,
    Dridzt = 1,
    Haleth = 1,
}

But this will raise an error, because you can't use strings that way:
Code:

local tbl = {
    "Phanx" = 1,
    "Clamsoda" = 1,
    "Seerah" = 1,
    "Dridzt" = 1,
    "Haleth" = 1,
}

On a side note, please never, ever name your table "table" -- that's already a global defined by WoW Lua, and is a table containing table-related functions, like table.insert, table.remove, table.sort, etc. More generally, you should never give anything the same name (even if it's local) as a global Lua function/object or a global WoW API function (eg. UnitName) or a global WoW UI object (eg. ChatFrame1). If your variable gets leaked into the global namespace, you will break other addons and/or the Blizzard UI and/or the UI in general. Even if it stays local, it's still just creating unnecessary confusion -- when you look at a part of your code using the variable, you have to figure out whether that code is referring to your local thing or the global thing with the same name -- and is a bad habit to be in.

Clamsoda 03-05-13 12:26 AM

They were general examples that I hand wrote in the message box. All of my variables have lengthy, well descriptive names.

Phanx 03-05-13 12:39 AM

Yes, but your "general examples" get copied and pasted as literal examples of working code by novices who don't know any better. :p

Clamsoda 03-05-13 12:42 AM

Touché, touché. :D

Also, thank you everyone for the input, it truly did help me get to where I wanted to be with my AddOn.


All times are GMT -6. The time now is 10:44 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI