【问题标题】:perl nested hash multiple sortperl 嵌套哈希多重排序
【发布时间】:2012-11-27 21:56:14
【问题描述】:

我的结构看起来像这样(散列):

$VAR1 = {
          'Lee2000a' => {
                'abstract' => 'Abstract goes here',
                'author' => 'Lee, Wenke and Stolfo, Salvatore J'
                'title' => 'Data mining approaches for intrusion detection'
                'year' => '2000'
              },
          'Forrest1996' => {
                'abstract' => 'Abstract goes here',
                'author' => 'Forrest, Stephanie and Hofmeyr, Steven A. and Anil, Somayaji'
                'title' => 'Computer immunology'
                'year' => '1996'
                }
        };

我想根据三个条件对这个结构进行排序(按此顺序):

1st - 根据年份值 (1996,2000) 2nd - 根据“外部”(Lee2000a,Forrest1996)结构键 第三 - 根据字母顺序的“内部”结构键(摘要、作者、标题、年份)。

到目前为止,我有两个代码需要以某种方式组合:

我。代码符合第二和第三条标准

for $i (sort keys(%bibliography)){
   print "$i => ", "\n";
   for $j (sort keys ($bibliography{"$i"})){
   print "\t $j -> ", $bibliography{"$i"}{"$j"},"\n";
   }
} 

二。代码满足第一个条件

for $i (sort { ($bibliography{$a}->{year} || 0) <=> ($bibliography{$b}->{year} || 0) } keys %bibliography){
  print "$i => ", "\n";
  for $j (sort keys ($bibliography{"$i"})){
    print "\t $j -> ", $bibliography{"$i"}{"$j"},"\n";
  }
}

非常感谢

【问题讨论】:

  • 请原谅我的无知,但是如何做到这一点,作为一个新手我对stackoverflow的概念不是很熟悉?另外,如果您能解释一下某些用户如何在此处粘贴代码,我只看到“添加评论”按钮,该按钮用于添加代码,然后使该代码变得可怕。 (我猜也有 600 个字符的限制)。非常感谢。
  • 您可能会发现FAQ 很有帮助,以及从那里链接的额外帮助。不过,具体来说,我看到您已经设法接受答案,这很好。对于粘贴代码,这取决于您为什么需要这样做。但通常,您只能将格式化的代码粘贴到问题或答案中 - 您不能在 cmets 中执行此操作。要正确设置其格式,请单击文本框上方的{ } 按钮以缩进以至少 4 个空格突出显示的所有内容。

标签: perl hashtable


【解决方案1】:

要按某些次要条件排序,您可以使用逻辑 OR:

my @sorted = sort {
                 $a{c1} <=> $b{c1} || 
                 $a{c2} <=> $b{c2}
             } @unsorted

此示例将通过键 c1@unsorted 中的哈希进行排序,然后,如果此比较相等,则使用键 c2

出于您的目的,您可以通过这种方式组合外部循环的两个排序比较,以便您的排序块将显示为:

(($bibliography{$a}->{year} || 0) <=> ($bibliography{$b}->{year} || 0)) ||
($a cmp $b)

【讨论】:

  • 这正是我所需要的。非常感谢。
【解决方案2】:

[UPDATE] 添加了一个更简单的版本,该版本仅根据排序条件返回输入哈希上的键。

第一种方法:返回排序列表

我们想要对哈希进行排序,排序条件包括键和嵌套在值中的内容。要进行 1 次排序,其中每个 $a$b 都可以进行比较,将哈希转换为一个列表可能会很方便,该列表使哈希中的每个键和值都可用。

有点浪费,但有效:

my @sorted = 
 sort {
    $a->{val}->{year} <=> $b->{val}->{year} ||             # 1st condition
    $a->{key} <=> $b->{key} ||                             # 2nd condition
    $a->{val}->{abstract} <=> $b->{val}->{abstract} ||     # 3rd condition
    $a->{val}->{author} <=> $b->{val}->{author} ||         # (not really sure
    $a->{val}->{title} <=> $b->{val}->{title} ||           # how you wanted this
    $a->{val}->{year} <=> $b->{val}->{year}
  } map { { val => $biblio{$_}, key => $_  }  } keys %biblio;

我们正在对哈希进行排序;我们需要一个列表作为返回值。在这种情况下,Forrest1996Lee2000a 适合在哪里?我认为将散列转换为 散列列表 可能有意义,其中每个散列都有 2 个属性 - keyval

所以排序的返回值将是这样的哈希列表:

@sorted = (
      {
        'val' => {
                   'title' => 'Computer immunology',
                   'author' => 'Forrest, Stephanie and Hofmeyr, Steven A. and Anil, Somayaji',
                   'abstract' => 'Abstract goes here',
                   'year' => 1996
                 },
        'key' => 'Forrest1996'
      },
      {
        'val' => {
                   'title' => 'Data mining approaches for intrusion detection',
                   'author' => 'Lee, Wenke and Stolfo, Salvatore J',
                   'abstract' => 'Abstract goes here',
                   'year' => 2000
                 },
        'key' => 'Lee2000a'
      }
  )

第二种方法:根据排序条件只返回一个键列表

我想,在阅读了 cmets 并重新考虑之后,只返回输入哈希的键就足够好和更轻了:

my @sorted = 
  sort {
    $biblio{$a}->{year} <=> $biblio{$b}->{year} ||         # 1st condition
    $a <=> $b ||                                           # 2nd condition
    $biblio{$a}->{abstract} <=> $biblio{$b}->{abstract} || # 3rd condition
    $biblio{$a}->{author} <=> $biblio{$b}->{author}        # ...and so on
   } keys %biblio;

...刚刚返回

 @sorted = (
      'Forrest1996',
      'Lee2000a'
 );

【讨论】:

  • 它可能会起作用,但为什么写它比使用两个for 循环更容易?
  • 您重新映射键/值对的原因是什么?生成的排序列表将是一个相当混乱的混乱。
  • 哈希没有顺序,对吧?所以我想需要返回一个列表/数组?这意味着,哈希的原始“密钥”必须保存在某个地方,尽管我称它为 key 有意义吗?
  • @TLP 好点 - 但是,什么是好的返回格式?仅包含哈希值的列表?
  • 好吧,假设原始散列仍然存在,键列表将是合适的。无需复杂化。
猜你喜欢
  • 2018-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 2013-12-04
  • 2020-12-09
相关资源
最近更新 更多