2015-01-12 23 views
5

Tabloları alfabetik olarak sıralamak istiyorum. Numaralar hariç.Lua tabloları alfabetik olarak sırala, sayılar hariç

aşağıdaki kod tablosu karşılaştırıcı fonksiyonu ile nasıl sıralandığını gösterir:

obj = { 
    [1] = { 
     ["N"] = "Green 1"; 
    }; 
    [2] = { 
     ["N"] = "Green 11"; 
    }; 
    [3] = { 
     ["N"] = "Green 2"; 
    }; 
    [4] = { 
     ["N"] = "Red 1"; 
    }; 
} 

Ama böyle sıralanabilir istiyorum::

function(a,b) return a.N < b.N end 

beni verir

obj = { 
    [1] = { 
     ["N"] = "Green 1"; 
    }; 
    [2] = { 
     ["N"] = "Green 2"; 
    }; 
    [3] = { 
     ["N"] = "Green 11"; 
    }; 
    [4] = { 
     ["N"] = "Red 1"; 
    }; 
} 

Mümkün mü?

+0

Sürücülerden tüm numaralar? Sadece ilk kelimeye göre mi sırala? vb. tablonuz büyükse ya da sık sık bunu yaptığınız "sort key" in bir önbelleğini saklamak muhtemelen iyi bir fikirdir. –

cevap

3

Bunu aslen gönderip yazacaktım, ancak lhf tarafından gönderilen çözüm, sorunuzu yanıtladı. Hala sorun yaşıyorsanız, aşağıdakileri deneyin.

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 

Baskılar: sıralamak önce anahtarından

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 
+0

Teşekkürler, bu daha iyi çalışır. Desen değiştirildi: ''(% D +) (% d +) $'' izin vermek için {N = 'Yeşil1'}, 'çalışmak gibi görünüyor ama bir şey gözden kaçmış olabilir. – Dreanh

+0

@Dreanh Bu desen iyi görünüyor ve renk adında hiçbir basamak olmadıkça çalışması gerekiyor, (. +) Herhangi bir karakter (ler) için çalışıyor. – Adam

+0

Tamam, teşekkürler. '^ (. +) (% D +) $' 'veya' '^ (% g) (% d +) $' 'kullanırsam işe yaramaz. – Dreanh

6

bu deneyin: "Yeşil 1" "Yeşil 02" ya da "Yeşil ile karşılaştırarak gibi, köşe davalarını gerekirse dikkate almak gerekebilir rağmen

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 
) 
+0

Teşekkürler! İstediğim gibi çalıştı! – Dreanh

+0

Bir sorun var, tablodaki bazı dizelerin sayısından bahsetmedik. Yani bir hata alıyorum. – Dreanh

+0

Bu satırda hata oluştu: 'a1 [b1 veya (a1 == b1 ve a2 Dreanh

3

lhf çözümü, sizin için çalışması gerektiğini @ 2 "Yeşil" ile "2". Alphanum sıralamasını uygulamak için birkaç yöntemi inceledim ve sonuçlarını bir blog post ile karşılaştırdım. Bu konu hakkında discussion on the lua mail list numaralı telefonu da kontrol edebilirsiniz.

İlgili konular