0

Below is a sample table structure of what I am wanting to sort.

Data = {
    ["C1_RN1::F1"] = {
        ["class"] = "Hunter",
        ["name"] = "C1",
        ["faction"] = "Faction",
        ["race"] = "Human",
        ["realm"] = "RN1",
    },
    ["C2_RN1::F1"] = {
        ["class"] = "Priest",
        ["name"] = "C2",
        ["faction"] = "Faction",
        ["race"] = "Undead",
        ["realm"] = "RN1",
    },
    ["C3_RN1::F1"] = {
        ["class"] = "Hunter",
        ["name"] = "C3",
        ["faction"] = "Faction",
        ["race"] = "Human",
        ["realm"] = "RN1",
    }
}

So for example I would like to sort by race alphabetically, and sort all the "Human" race characters by class also alphabetically, and sort any other "races" also by alphabetically independent of another "race".

I know how to sort by just one by dumping all the character names into a 2nd table with the same keys as the data table, and then comparing data in the data table using table.sort and a that compares data with the less than operator such as data[a].race < data[b].race.

This is the function I tried to use to a basic sort, but this doesn't work using Lua 5.1, i get an error saying there should be an = after the <.

local function SortThis()
    local temp = {}

    for c in pairs(Data) do
        table.insert(temp, c);
    end

    table.sort(temp, function(a, b)
        return Data[a].race < RestXP_Data[b].race;
    end)
end
2
  • 2
    Currently there is nothing to sort, as you have associative-array type tables (arbitrarily ordered keys and values). Are you saying you want to convert Data into an array-like table (one with numerical indices), which is sorted by multiple conditions? Commented Nov 5, 2023 at 20:20
  • @Oka I will add my function to the question, albeit the function doesn't work it gives lua errors, but I'll explain that also. Commented Nov 6, 2023 at 0:04

1 Answer 1

3

Currently there is nothing to sort, as you have associative-array type tables, which will always have arbitrarily ordered keys and values. You can only sort array-like tables (those with numerical indices).

In your comparison function, simply check if your primary comparison is equal, in which case you move on to your secondary comparison (and then tertiary comparison, etc...). If a key comparison is not equal, return the appropriate result for that key (i.e., < or >).

Note that table.sort is not stable.

local data = {
    ["C1_RN1::F1"] = {
        ["class"] = "Warrior",
        ["name"] = "C1",
        ["faction"] = "Faction",
        ["race"] = "Human",
        ["realm"] = "RN1",
    },
    ["C2_RN1::F1"] = {
        ["class"] = "Priest",
        ["name"] = "C2",
        ["faction"] = "Faction",
        ["race"] = "Undead",
        ["realm"] = "RN1",
    },
    ["C3_RN1::F1"] = {
        ["class"] = "Hunter",
        ["name"] = "C3",
        ["faction"] = "Faction",
        ["race"] = "Human",
        ["realm"] = "RN1",
    }
}

local collapsed = {}

for key, value in pairs(data) do
    table.insert(collapsed, value)
end

table.sort(collapsed, function (a, b)
    if a.race == b.race then
        return a.class < b.class
    end

    return a.race < b.race
end)

for _, character in ipairs(collapsed) do
    print(character.name, character.race, character.class)
end
C3  Human   Hunter
C1  Human   Warrior
C2  Undead  Priest

If you have a lot of keys to compare, you can loop through them.

table.sort(collapsed, function (a, b)
    local order = { 'race', 'class', 'realm' }

    for _, key in ipairs(order) do
        if a[key] ~= b[key] then
            return a[key] < b[key]
        end
    end
end)
Sign up to request clarification or add additional context in comments.

1 Comment

I'm limited to using Lua 5.1 as the code is for a game, and they currently use that. As for the code with the table.sort(collapsed that's similar to what I was doing, expect I didn't have an if, everything else was the same however. I will give that a try.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.