aJynks
aJynks

Reputation: 689

How to order a Table to tables based on 1 single data part of it?

I am a hobbyest making mods in TableTop Simulator using LUA and have a question that I can not seam to work out.

I have a number of "objects" which is a table in TTS that contains various data for those objects. For example.. obj.position = {x,y,z}... and can be accessed at the axis level as well.

obj.position = {5,10,15} -- x,y,z
obj.position.x == 5

This is an example. The makers of TTS have made it so you can access all the parts like that. So I can acess the object.. and then its various parts. There is a heap, like name, mesh, difuse and a ton more. roations{x,y,z} etc etc

Anyway. I have a table of objects... and would like to order those objects based on the positional data of the x axis.. so highest to lowest. So if I have a table and obj1 in that table is x=3 and obj2 is x=1 and obj3 = x=2 it would be sorted as obj2,obj3,obj1

Pseudo code:

tableOfObjects = {obj1,obj2,obj3}
--[[
tableOfObjectsp[1] == obj1
tableOfObjectsp[2] == obj2
tableOfObjectsp[3] == obj3

tableOfObjectsp[1].position.x == 3
tableOfObjectsp[2].position.x == 1
tableOfObjectsp[4].position.x == 2
--]]
---After Sort it would look this list
tableOfObjects = {obj1,obj3,obj2}
    --[[
tableOfObjectsp[1] == obj1
tableOfObjectsp[2] == obj3
tableOfObjectsp[3] == obj2

tableOfObjectsp[1].position.x == 3
tableOfObjectsp[2].position.x == 2
tableOfObjectsp[3].position.x == 1
--]]

I hope I am making sense. I am self taught in the last few months!

So basically I have a table of objects and want to sort the objects in that table based on a single value attached to each individual object in the table. In this case the obj.position.x

Thanks!

Upvotes: 2

Views: 262

Answers (3)

mike bayko
mike bayko

Reputation: 385

you can create a function that handles this exact thing:

local function fix_table(t)
    local x_data = {};
    local inds = {};
    local rt = {};
    for i = 1, #t do
        x_data[#x_data + 1] = t[i].position.x;
        inds[t[i].position.x] = t[i];
    end
    local min_index = math.min(table.unpack(x_data));
    local max_index = math.max(table.unpack(x_data));
    for i = min_index, max_index do
        if inds[i] ~= nil then
            rt[#rt + 1] = inds[i];
        end
    end
    return rt;
end
local mytable = {obj1, obj2, obj3};
mytable = fix_table(mytable);

fix_table first takes in every x value inside of the given table, and also places a new index inside the table inds according to each x value (so that they will be ordered from least to greatest), then it gets the smallest value in the x_data array table, which is used to traverse the inds table in order. fix_table checks to make sure that inds[i] is not equal to nil before it increases the size of the return table rt so that every value in rt is ordered from greatest to least, starting at index 1, and ending at index #rt, finally rt is returned.

I hope this helped.

Upvotes: -3

Piglet
Piglet

Reputation: 28950

table.sort(tableOfObjects, function(a, b) return a.position.x > b.position.x end)

This line will sort your table tableOfObjects in descending order by the x-coordinate.

To reverse order, replace > by <.

From the Lua reference manual:

table.sort (list [, comp])

Sorts list elements in a given order, in-place, from list[1] to list[#list]. If comp is given, then it must be a function that receives two list elements and returns true when the first element must come before the second in the final order (so that, after the sort, i < j implies not comp(list[j],list[i])). If comp is not given, then the standard Lua operator < is used instead.

Note that the comp function must define a strict partial order over the elements in the list; that is, it must be asymmetric and transitive. Otherwise, no valid sort may be possible.

The sort algorithm is not stable: elements considered equal by the given order may have their relative positions changed by the sort.

So in other words table.sort will sort a table in ascending order by its values. If you want to order descending or by something other than the table value (like the x-coordinate of your table value's position in your case) you have to provide a function that tells Lua which element will come first.

Upvotes: 0

Milo Christiansen
Milo Christiansen

Reputation: 3294

You need table.sort. The first argument is the table to sort, the second is a function to compare items.

Example:

t = {
    {str = 42, dex = 10, wis = 100},
    {str = 18, dex = 30, wis = 5}
}

table.sort(t, function (k1, k2)
    return k1.str < k2.str
end)

This article has more information

Upvotes: 3

Related Questions