Вопрос по alphanumeric, sorting, perl – Как сделать буквенно-цифровую сортировку perl?

0

У меня есть файл, который выглядит так:

80,1p21  
81,19q13  
82,6p12.3  
83,Xp11.22  
84,3pter-q21  
86,3q26.33  
87,14q24.1-q24.2|14q24|14q22-q24  
88,1q42-q43  
89,11q13.1  
90,2q23-q24  
91,12q13  
92,2q22.3  
93,3p22  
94,12q11-q14  
95,3p21.1  
97,14q24.3  
98,2p16.2  

И я хочу отсортировать их по второму столбцу. И первый столбец тоже должен измениться. Когда вы используете команду сортировки в perl, она этого не делает, потому что говорит, что она не числовая. Есть ли способ отсортировать вещи по алфавиту в Perl?

Благодарю.

@lanZZ: документация по сортировке из perl не сильно помогла. Если я использую лексическую сортировку, она сортирует 1p21 19q13 6p12.3 11q13.1 2q23-q24 как 11q13.1 19q13 1p21 2q23-q24 6p12.3. Что не то, что мне нужно. Jordan
Почему RTFM получает четыре отзыва? Если вы не хотите отвечать на вопросы начинающих, то просто не отвечайте на них. Нет ничего плохого в том, чтобы указывать документы, но предоставьте некоторую ценность с помощью ссылки, как это сделал Дейв Кросс ниже. Len Jaffe
Этот вопрос задавался здесь много раз. И это довольно хорошо описано в документации. Теперь позвольте мне спросить вас: разве вы не говорите, что игнорирование поиска - это то, что нужно делать новичкам? На мой взгляд, на самом деле все наоборот: для начинающего еще важнее начать использовать поиск как можно скорее. raina77ow
Также, если они уже есть в файле, вы можете попробовать команду сортировки unix. Сценарий Perl для сортировки файла является излишним. Mark Tozzi
@Ianzz: То есть вы, полиция SO, применяете «Задавать нетривиальные вопросы или RTFM»? политика? Используйте SO, чтобы научить больше, чем & quot; Go теряться на 5000 страницах perl docs. & Quot; Научите, "Вот", как найти это на 5000 страницах документов "," Здесь "и другие важные вещи, которые следует учитывать при выборе правильного ответа на ваш вопрос". Обучайте навыкам рыбной ловли, не говорите им просто ловить рыбу. Len Jaffe

Ваш Ответ

3   ответа
4

Если вы читаетедокументация для сортировки, вы увидите, что вам не нужно выполнять числовую сортировку в Perl. Вы можете сделать сравнение строк тоже.

@sorted = sort { $a cmp $b } @unsorted;

Но это все еще оставляет проблему, так как, например, 19q будет сортировать до 6p. Таким образом, вы можете написать свою собственную функцию сортировки, которая может делать любые преобразования, которые вы хотите, прежде чем делать сравнение.

@sorted = sort my_complex_sort @unsorted;

sub my_complex_sort {
  # code that compares $a and $b and returns -1, 0 or 1 as appropriate
  # It's probably best in most cases to do the actual comparison using cmp or <=>

  # Extract the digits following the first comma
  my ($number_a) = $a =~ /,(\d+)/;
  my ($number_b) = $b =~ /,(\d+)/;

  # Extract the letter following those digits
  my ($letter_a) = $a =~ /,\d+(a-z)/;
  my ($letter_b) = $b =~ /,\d+(a-z)/;

  # Compare and return
  return $number_a <=> $number_b or $letter_a cmp $letter_b;
}
Sort::Naturally
0

хотя.

#!/usr/bin/env perl

use strict;  
use warnings;

sub main {   
my $file;  
if (@ARGV != 1) {   
    die "Usage: perl hashofhash_sort.pl <filename>\n";
}   
else {  
    $file = $ARGV[0];   
}  

open(IN, $file) or die "Error!! Cannot open the $file file: $!\n";
my @file = <IN>;
chomp @file;
my ($entrez_gene, $loci, $chr, $band, $pq, $band_num);
my (%chromosome, %loci_entrez);

foreach my $line (@file) {
    if ($line =~ /(\d+),(.+)/) {
        # Entrez genes
        $entrez_gene = $1;

        # Locus like 12p23.4
        $loci = $2;

        if ($loci =~ /^(\d+)(.+)?/) {
            # chromosome number alone (only numericals)
            $chr = $1;
            if ($2) {
                # locus minus chromosome number. If 12p23.4, then $band is p23.4
                $band = "$2";
                if ($band =~ /^([pq])(.+)/) {
                    # either p or q
                    $pq = $1;
                    # stores the numericals. for p23.4, stores 23.4
                    $band_num = $2;
                }

                if (exists $chromosome{$chr}) {
                    if (exists $chromosome{$chr}{$pq}) {
                        push (@{$chromosome{$chr}{$pq}}, $band_num);
                    }
                    else {
                        $chromosome{$chr}{$pq} = [$band_num];
                    }
                }

                else {
                    $chromosome{$chr}{$pq} = [$band_num];
                }
            }
        }
    }
} # End of foreach loop

foreach my $key (sort {$a <=> $b} keys %chromosome) {
    my %seen = ();
    foreach my $key2 (sort {$a cmp $b } keys %{$chromosome{$key}}) {
        my @unique = grep { ! $seen{$_}++ } @{$chromosome{$key}{$key2}};
        my @sorted = sort @unique;
        foreach my $element (@sorted) {
            my $sorted_locus = "$key$key2$element";
            if (exists $loci_entrez{$sorted_locus}) {
                foreach my $element2 (@{$loci_entrez{$sorted_locus}}) {
                        print "$element2,$sorted_locus\n";

                }
            }
        }
    }

}


} # End of main

main();
0
#!/usr/bin/env perl

use strict;
use warnings;

my @datas   = map { /^(\d+),(\d*)(.*)$/; [$1, $2, $3]; } <DATA>;
my @res     = sort {$a->[1] <=> $b->[1] or $a->[2] cmp $b->[2]} @datas;
foreach my $data (@res) {
    my ($x, $y, $z) = @{$data};
    print "$x,$y$z\n";
}

__DATA__
80,1p21
81,19q13
82,6p12.3
83,Xp11.22
84,3pter-q21
86,3q26.33
87,14q24.1-q24.2|14q24|14q22-q24
88,1q42-q43
89,11q13.1
90,2q23-q24
91,12q13
92,2q22.3
93,3p22
94,12q11-q14
95,3p21.1
97,14q24.3
98,2p16.2 
Вы можете объяснить свой ответ за пределы кода.
Это будет, например, сортировать 19q13 до 6p12.3. Я не думаю, что это то, что хотел ОП.

Похожие вопросы