how can we check wether similar elements are present in table in lua in minimum time complexity - lua

if a table of N integer is present how to check if an element is repeating if present it shows message that table has repeating elements, if this is to be achieved in minimum time complexity

Hash table is the way to go (ie normal Lua table). Just loop over each integer and place it into the table as the key but first check if the key already exists. If it does then you have a repeat value. So something like:
values = { 1, 2, 3, 4, 5, 1 } -- input values
local htab = {}
for _, v in ipairs(values) do
if htab[v] then print('duplicate value: ' .. v)
else htab[v] = true end
end
With small integer values the table will use an array so will be O(1) to access. With larger and therefore sparser values the values will be in the hash table part of the table which can just be assumed to be O(1) as well. And since you have N values to insert this is O(N).
Getting faster than O(N) should not be possible since you have to visit each value in the list at least once.

Related

Get index of maximum values from table in Lua

Suppose that I have a table:
0.8
0.7
0.9
0.5
And I want to get the index of 2 largest values, so in this case, it should return:
3 1
I am quite newbie with Lua, so any help is more than welcome.
Thanks a lot,
You can loop over a table using for loop (for i = 1, #tbl or for i, val in ipairs(tbl)) and keep track of the largest and second to large elements (you'll need to store first index and first value and second index with second value to check the value and save the index). After the loop is done, you get the indexes of the first and second largest elements. Keep in mind that when the first value is updated its old value may need to be checked against the second value.
Another option is to build an array of indexes and sort it based on the values (as the sort can take an optional comparator function):
local function indexsort(tbl)
local idx = {}
for i = 1, #tbl do idx[i] = i end -- build a table of indexes
-- sort the indexes, but use the values as the sorting criteria
table.sort(idx, function(a, b) return tbl[a] > tbl[b] end)
-- return the sorted indexes
return (table.unpack or unpack)(idx)
end
local tbl = {0.8, 0.7, 0.9, 0.5}
print(indexsort(tbl))
This prints 3 1 2 4. If you only need the first two indexes, you can do local first, second = indexsort(tbl). Note that indexsort returns all indexes, so if you only need the first two (and your table is large), you may want to update the function to only return the first two items instead of the entire table.

How can I find the position of several repeated highest values in a table?

I have a table in Lua with, for example:
Array = {5,3,5}
And I want, if possible, a function that returns the position of the highest values.
Probably an easy question but I cannot find the solution...
math.max returns the maximum value. To get the index:
local t = {5,3,5}
local max = math.max(table.unpack(t))
for i, v in ipairs(t) do
if v == max then
print(i)
end
end
Note that the table is passed twice here. If the table is huge, pass the table once and store the highest value and compare manually.

remove all entries with specified value in table

I want to delete all entries from a table, wich equals a given value.
Now, I got a pretty little problem one might to know, how to handle.
This is the Code:
function(list_to_search_in, compared_value, invert)
for k,v in pairs(list_to_search_in) do
if invert and v ~= compared_value then
table.remove(list_to_search_in, v)
if not invert and v == compared_value then
table.remove(list_to_search_in, v)
end
end
end
The Problem:
Let's say the table is { 1, 2, 3, 2 }. So when I'm iterating through that loop and come to the first match, it's removed from the table. This means the value and the key is deleted.
Now the key of the deleten value is assigned to the next value in line. But due the skript will check the value of the next key, this value (whichs kay has been just altered) will never be checked.
I thought, a simple
k = k - 1
after a remove would do the job, but it doesn't.
v = nil
would do great I think, but only if garbage-collector does not do his job in this very moment the pairs iterates to the next value.
Anyone has an idea? I would prefer an text-based hint to a finished syntax which solves the problem.
Don't use table.remove for this. It squeezes the "hole" out of array-like tables. That's not allowed during an iteration using pairs/next. Just set the value to nil.
If you need to squeeze holes out of the table then you can either create a new table and populate it with only the values you want to keep or do the removals during the first pass and then squeeze out holes in a second pass.
Also the order of item traversal when using pairs is not guaranteed in any way.

Lua table continues to be empty, even though I am giving it stuff

In my Lua-powered game, I am trying to create an Explorer to see all the instances that have been created. I've created a function inside my DataModel "class" (as I like to call it) that will scan the children of an item, and put it neatly inside a table.
function DataModel.ObjectToTable(obj)
children = {}
for i,v in pairs(obj:GetChildren()) do
table.insert(children, DataModel.ObjectToTable(v))
end
print(obj.Name)
dmyself = {}
dmyself.Name = obj.Name
dmyself.Object = obj
dmyself.Children = children
print(#dmyself)
return dmyself
end
The issue is that, the print(#dmyself) is coming out as 0. But as you can see, I just set 3 things inside of it. What could cause such a thing to happen? Am I doing something obviously wrong?
The print(obj.Name) line is returning what it should. I am simply stuck on 'dmyself'.
# is the length of the array part of the Lua table; it only takes integer keys into account. More specifically,
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil, n can be zero. For a regular array, with non-nil values from 1 to a given n, its length is exactly that n, the index of its last value.
If you use pairs, you can see that your table is not empty. But since there's nothing in the array part of the table, it's length is zero.

Assign table to table in Lua

In Lua, I can add an entry inside table with table.insert(tableName, XYZ). Is there a way I can add already existing table into table? I mean a directly call rather then traversing and add it.
Thanks
The insert in your example will work fine with whatever contents happen to be inside the XYZ variable (number, string, table, function, etc.).
That will not copy the table though it will insert the actual table. If you want to insert a copy of the table then you need to traverse it and insert the contents.
First: In general, you do not need table.insert to put new entries into tables.
A table in Lua is a collection of key-value pairs; entries can be made like this:
local t = {} --the table
local key= "name"
local value = "Charlie"
t[key] = value --make a new entry (replace an existing value at the same key!)
print(t.name) --> "Charlie"
Note that key can have any type (not just integer/string)!
Very often you will need tables for a simple special case of this: A sequence ("list", "array") of values. For Lua, this means you want a table where all the keys are consecutive integers, and contain all non-nil values. The table.insert function is intended for that special case: It allows you to insert a value at a certain position (or to append it at the end of the sequence if no position is specified):
local t = {"a", "b", "d"} --a sequence containing three strings (t[1] = "a", ...)
table.insert(t, "e") --append "e" to the sequence
table.insert(t, 3, "c") --insert "c" at index 3 (moving values at higher indices)
--print the whole sequence
for i=1,#t do
print(t[i])
end
If I understand what you mean correctly, you want to do this:
local t1 = {1, 2, 3}
local t2 = {4, 5, 6}
some_function(t1, t2)
-- t1 is now {1, 2, 3, 4, 5, 6}
There is indeed no way to do this without iterating t2. Here is a way to write some_function:
local some_function = function(t1, t2)
local n = #t1
for i=1,#t2 do t1[n+i] = t2[i] end
end
No, you must copy the second table's key/value pairs into the first table. Copying the existing values from the second table is what's known as a "shallow copy." The first table will reference the same objects as the second table.
This works under limited circumstances:
local n = #t1
for i=1,#t2 do t1[n+i] = t2[i] end
It does attempt to shift the t2 elements to just beyond the existing t1 elements. That could be a vital requirement but wasn't stated in the question.
It has a few of problems, though:
By using #t1 and #t2, it misses keys that aren't positive integers and can miss keys that are integers greater than a skipped integer key (i.e. never assigned or assigned nil).
It accesses the first table with an indexer so could invoke the __newindex metamethod. That probably wouldn't be desirable when only copying is wanted.
It accesses the second table with an indexer so could invoke the __index metamethod. That wouldn't be desirable when only copying is wanted.
You might think that ipairs could be used if only positive integer keys are wanted but it quits on the first nil value found so could miss even more than #t2 does.
Use pairs instead:
for key, value in pairs(t2) do
rawset( t1, key, value )
end
If you do want to avoid replacing existing t1 values when the keys match or otherwise map t2 keys in some way then that has to be defined in the requirements.
Bottom line: pairs is the way to get all the keys. It effectively does a rawget so it avoids invoking __index. rawset is the way to do a copy without invoking __newindex.

Resources