【问题标题】:sort hash key in perl with key being tab separated在 perl 中对哈希键进行排序,键是制表符分隔的
【发布时间】:2020-11-10 02:05:30
【问题描述】:

我有一个数组哈希(perl),其键是一个由制表符连接的字符串。 这就是哈希键的样子

chr"\t"fivep"\t"threep"\t"strand  # separated on tab

如果哈希被命名为%output

我想对这个散列的键进行排序,这样首先对 chr 进行排序,然后在 Fivep 上进行排序,然后在 threep 上进行排序。

我尝试了以下代码进行排序:

foreach my $k(sort keys %output){
    print join("\t",$k,@{$output{$k}}),"\n";    
}

这仅对 chr 进行排序,但我想在其后排序 5p,然后再排序 3p。

我该怎么做?

【问题讨论】:

  • 不是一个完全成熟的解决方案,但是当我尝试对类似数据进行排序时,我发现Sort::Versions 非常方便并且能够轻松地对这些类型的字符串进行排序。我通常会用它来排序像chr1:12345:T>A 这样的东西,它处理得很好。先尝试一下可能很简单?
  • 您是否考虑在填充哈希时更改密钥本身?然后,您的代码将按原样运行。
  • 是的,我有。可能是这样的数组散列@{$output{$chr}->{$fivep}->{$threep}->{$strand}}。然后使用 foreach 循环打印输出。效果很好。

标签: perl sorting hash


【解决方案1】:

我将建议您对键进行转换,然后进行自定义排序。

for my $k (
    map { $_->[0] } # pull out the original key
    sort { $a->[1] cmp $b->[1] || $a->[2] cmp $b->[2] || $a->[3] cmp $b->[3] } # do the actual sort
    map { [ $_, split /\t/, $_, -1 ] } # split the keys and make the transform
    keys %output
) {
     print join "\t", $k, @output{$k};
}

如果sort 代码块过于复杂或者该过程需要在代码中的更多位置重用,您可以将其分解到它自己的函数中,然后只为sort 提供函数。

【讨论】:

  • 应该是split /\t/, $_, -1 而不是split /\t/, $_。空字段在 TSV 文件中很常见。
【解决方案2】:

我认为https://metacpan.org/pod/Sort::Key::Maker 可以满足您的需求。以下代码应该适合您。

use Sort::Key::Maker custom_sort => qw(str str str);
my @sorted = custom_sort { (split /\t/, $_, -1)[ 0 .. 2 ] } keys %output;

【讨论】:

  • 谢谢@ikegami。我已根据您的建议更新了答案。
猜你喜欢
  • 1970-01-01
  • 2015-03-12
  • 2015-08-21
  • 2019-03-17
  • 1970-01-01
  • 1970-01-01
  • 2018-05-10
  • 2021-12-07
  • 1970-01-01
相关资源
最近更新 更多