2016-04-02 10 views
3

Numaraları sıralamalıyım ve istediğim şekilde çalışamıyorum.Perl sayıları doğal olarak

Örnek giriş:

15.12 
16.1 
15.2 
15.1 

Beklenen çıkışı:

15.1 
15.2 
15.12 
16.1 

Normal tür çalıştı ve bu da aynı zamanda Sort::Naturally. Ne beklenen çıktıyı bana veriyor.

Ayrıca, istediğim gibi sıralamak için aşağıdaki gibi bir şey yapabileceğimin de farkındayım.

my @sorted = 
map sprintf('%vd', $_), 
sort 
map join('', map chr, split /\./), 
@data; 

Kullanabileceğim bazı önceden var olan modüllerin olup olmadığını merak ediyorum.

Şimdiden teşekkürler.

cevap

3

. Sırala :: Doğal olarak çalışmaz, çünkü alfasayısal olmayan karakterleri yok sayar, ancak bunu yapabilecek birkaç modül vardır.

Sort::Versions

ya da tireler üzerindeki giriş böler ve non-basamaklı karakterler mevcut olup olmamasına bağlı olarak, ya alfabetik veya sayısal her grubu sıralar:

use strict; 
use warnings 'all'; 
use 5.010; 

use Sort::Versions; 

my @versions = (
    15.12, 
    16.1, 
    15.2, 
    15.1 
); 

say for sort { versioncmp($a, $b) } @versions; 

Çıkış:

15.1 
15.2 
15.12 
16.1 

Sıralama :: Sürümler, girdinin belirli ortak sürüm dizesi formatlarıyla eşleşmesini bekler; Gösterdiğinizden farklı biçimler ayırmanız gerekiyorsa, bunun sizin için çalışacağından emin olmak için belgelerindeki kuralları kontrol edin. tüm sözcük sınırları değil, sadece dönem ve tire üzerinde böler, ancak bu durumda aynı şekilde çalışır, çünkü


Sort::Key::Natural daha esnektir:

use strict; 
use warnings 'all'; 
use 5.010; 

use Sort::Key::Natural qw(natsort); 

my @versions = (
    15.12, 
    16.1, 
    15.2, 
    15.1 
); 

say for natsort @versions; 

(Çıktı Sıralama için aynıdır: : Sürümler)

Sıralama :: Anahtar :: Natural, sıralama düzenini özelleştirmek ve sıralamak için yeteneği gibi bazı güzel ek özelliklere sahiptir. Ayrıca, sıralamalarımdaki Sıralama :: Sürümler'den önemli ölçüde daha hızlıydı, ancak bu yalnızca büyük dizileri sıralamanızla ilgili olacak.

+0

Bana standart kayan nokta sayıları gibi görünüyorlar. Bu sürüm dizeleri – Borodin

+0

@Borodin'in beklenen çıktıya baktığını varsaymak için büyük bir adım. 15.12'den önce 15.2 sıralamak istiyorlar. – ThisSuitIsBlackNot

+0

Haklısınız. Bu ince. İyi çağrı – Borodin

3

Numaraları, özel $a ve $b değişkenleriyle karşılaştırmalısınız (<=>). <=>'u cmp ile değiştirerek dizelerle aynı şeyi yapabileceğinizi unutmayın.

use warnings; 
use strict; 

my @nums = qw(15.1 16.1 15.12); 

@nums = sort {$a <=> $b} @nums; 

print "$_\n" for @nums; 

__END__ 
15.1 
15.12 
16.1 
6

bunu anlasalardı doğru, bunu .12 sizin örnek (12> 2) gibi .2 daha büyüktür, birinci tamsayı değeri ile sayılar sıralamak ve daha sonra bir tamsayı kendisi kadar ondalık kısmı düşünebilirsiniz.

Dediğin gibi en öz açıklayıcı yolu onları ayrıldıktan sonra, özel bir tür kullanmaktır düşünüyorum: Eğer her bileşen bağımsız sıralanır nerede, sürüm numaraları sıralamak için çalışıyoruz gibi görünüyor

@sorted = sort { 
    my ($a1, $a2) = split /\./, $a; 
    my ($b1, $b2) = split /\./, $b; 
    $a1 <=> $b1 or $a2 <=> $b2 
} @numbers;