why does this code not find the maxmimum value in my table ?

my table contains some big numbers, such as 1884882022.4

when I attempt to try and find the max value in the table using the code below, it reports 99997.1 as the maximum value, which is incorrect. Can someone explain why the code below doesn't work for my data ?

function find_max( t )
if t == nil or type( t ) ~= 'table' then
return nil;
end

local max = t[1];
for k, v in pairs( t ) do
if( v > max ) then max = v; end
end
return max;
end

Not sure if this is it, but I think it is due to using the "pairs" iterator. "Pairs" implies that your table is full of named indexes instead of numerical indexes, like:

t["cat"] = 20
t["dog"] = 412

So it is looking for named references like that. If you don't have any, I don't believe it will return anything (not sure though)

Since you defined max = t[1] then I am assuming you are not using named indexes in the table. So you might want to try:

1
2
3
4
5
6
7
8
9
10
11
12
13
    for j=1,#t do
         if t[j] > max then
            max = t[j]
         end
    end
 
   ------
   -- OR
   ------
 
   for k,v in ipairs(t) do
          if( v > max ) then max = v; end
   end

I tried that as my first solution, and it didn't work.

Then I found this statement, which could apply to me as my table has 88,573 elements...

"This will not work for larger tables, as there is a limit for a number of arguments and number of return values in each Lua implementation"

Interesting. I tried the below self-contained code at it seemed to work. And I was wrong about the pairs thing since it works in the below code, so I'll have to look more into that. So since the below worked for me, I'm not quite sure how your code is different...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
local bigTable = {}
local firstMax = 0
for j=1,88573 do
        bigTable[j] = math.random(2000000000) + math.random(99)/100
        if bigTable[j] > firstMax then
                firstMax = bigTable[j]
        end
end
 
--plant the highest value, so that I know what the highest value is supposed to be
local randPosition = math.random(#bigTable)
bigTable[randPosition] = 3000000000.456
 
local function findMax(t)
        if t == nil or type( t ) ~= 'table' then
                return nil;
        end
        
        local max = t[1]
        --find max
        for k, v in pairs( t ) do
                if( v > max ) then max = v; end
        end
        
        --[[
        for j=1,#t do
                if t[j] > max then
                        max = t[j]
                end
        end
        --]]
        
        return max
end
 
local newMax = findMax(bigTable)
 
print(firstMax,newMax,#bigTable)

perhaps if I can offer the data in a text file, to demonstrate:
http://www.drivelink.com/test.txt

if I run your code, it tells me the max number is
99997.1

when the correct answer is
1884882022

Ah! I think I know what it is. Make sure you convert each number to a "number". If you are loading the values from a file, it will consider the values strings and not numbers and you will probably get some unexpected values. So use tonumber() on each value before putting it into the table.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
local bigTable = {}
        
local path = system.pathForFile("testData.txt",system.resourceDirectory)
local file = io.open(path,"r")
 
for line in file:lines() do
        bigTable[#bigTable+1] = tonumber(line)
end
 
io.close(file)
 
path = nil
file = nil
 
 
local function findMax(t)
        if t == nil or type( t ) ~= 'table' then
                return nil;
        end
        
        local max = t[1]
        --find max
        for k, v in pairs( t ) do
                if( v > max ) then max = v; end
        end
        
        --[[
        for j=1,#t do
                if t[j] > max then
                        max = t[j]
                end
        end
        --]]
        
        return max
end
 
local newMax = findMax(bigTable)
 
print(newMax,#bigTable)

the numbers are stored in a table. I just created the txt file for convenience so you could check them out.

So with the values in the table already being numbers, does that mean I need something different than tonumber or does the same principle apply ?

BINGO!

Your tonumber idea worked a treat and I can now find the max value no problem.

Big THANK YOU!

When I tried the previous code I posted it seems to work. With this line:

bigTable[#bigTable+1] = tonumber(line)

I get the correct high value every time.

If use instead:

bigTable[#bigTable+1] = line

I get 99997.1 as my value every time. The same value you were getting.

So that made me think your values are strings and not numbers.

How about seeing what type() prints out on the values in your table?

nice!

views:1444 update:2011/12/30 9:10:41
corona forums © 2003-2011