I would want to sort a table alphabetically. Except numbers.
The code below shows how the table is sorted with comparator function:
function( a,b ) return a.N < b.N end
Gives me:
obj = {
[1] = {
["N"] = "Green 1";
};
[2] = {
["N"] = "Green 11";
};
[3] = {
["N"] = "Green 2";
};
[4] = {
["N"] = "Red 1";
};
}
But I want it to be sorted like this:
obj = {
[1] = {
["N"] = "Green 1";
};
[2] = {
["N"] = "Green 2";
};
[3] = {
["N"] = "Green 11";
};
[4] = {
["N"] = "Red 1";
};
}
Is it possible?
Try this:
local function split(a)
local x,y=a.N:match("(%S+)%s+(%S+)")
return x,tonumber(y)
end
table.sort(obj,
function (a,b)
local a1,a2=split(a)
local b1,b2=split(b)
return a1<b1 or (a1==b1 and a2<b2)
end
)
Was going to post this originally, but the solution posted by lhf answered your question. Since you are still having issues, give the following a try.
local function cmp(a, b)
a = tostring(a.N)
b = tostring(b.N)
local patt = '^(.-)%s*(%d+)$'
local _,_, col1, num1 = a:find(patt)
local _,_, col2, num2 = b:find(patt)
if (col1 and col2) and col1 == col2 then
return tonumber(num1) < tonumber(num2)
end
return a < b
end
local obj = {
{ N = '1' },
{ N = 'Green1' }, -- works with optional space
{ N = 'Green' }, -- works when doesn't fit the format
{ N = 'Sky blue99' },
{ N = 'Green 11' },
{ N = 'Green 2' },
{ N = 'Red 02' }, -- works when has leading zeros
{ N = 'Red 01' }, -- works with padding spaces
{ N = 'Sky blue 42' }, -- works with multi-word color names
{ N = 99 }, -- works with numbers
}
table.sort(obj, cmp)
for i,v in ipairs(obj) do
print(i, v.N)
end
Prints:
1 1
2 99
3 Green
4 Green1
5 Green 2
6 Green 11
7 Red 01
8 Red 02
9 Sky blue 42
10 Sky blue99
@lhf's solution should work for you, although you may need to consider if you need to handle corner cases, like comparing "Green 1" with "Green 02" or "Green 2" with "Green 02". I've reviewed several methods to implement alphanum sorting and compared their results in a blog post. You may also check the discussion on the lua mail list on this very topic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With