【问题标题】:Sort an array based on a substring in the array element根据数组元素中的子字符串对数组进行排序
【发布时间】:2019-03-26 21:16:54
【问题描述】:

有没有一种方法可以根据数组元素的子字符串对数组进行排序。例如,假设我有以下数组:

@myArray = qw("AAA|111|bbb" "CCC|333|ddd" "EEE|444|fff" "GGG|222|hhh");

我想根据从位置 4(从零开始)开始长度为 3(在我的示例中的第一个数组元素中为“111”)的子字符串对该数组进行排序。

每个数组元素的长度对于所有元素将始终相同,并且我要排序的子字符串将始终在数组元素中相同长度的相同位置。

这是我的排序输出的样子:

AAA|111|bbb

GGG|222|hhh

CCC|333|ddd

EEE|444|fff

此外,虽然我在示例中将数字显示为子字符串,但其中也可能是非数字值。所以排序也必须适用于非数字。

【问题讨论】:

    标签: perl sorting substring


    【解决方案1】:

    sort 可以采用第一个参数,即比较两个元素的代码块:

    #!/usr/bin/perl
    use warnings;
    use strict;
    use feature qw{ say };
    
    my @myArray = qw( AAA|111|bbb CCC|333|ddd EEE|444|fff GGG|222|hhh );
    
    
    say for sort { substr($a, 4, 3) cmp substr($b, 4, 3) } @myArray;
    

    另见substr

    请注意,我从qw() 中删除了双引号。 “qw”代表“引用词”,因此不需要引号(事实上,它们会成为您不想要的字符串的一部分)。

    使用Sort::Key 模块,它可以变得更加简单:

    use Sort::Key qw{ keysort };
    ...
    say for keysort { substr $_, 4, 3 } @myArray;
    

    【讨论】:

      【解决方案2】:

      如果这是固定长度字段的记录,管道有什么用?

      如果您将输入视为管道分隔值,那么您的代码将变为

      say for sort { ( split /\|/, $a )[1] <=> ( split /\|/, $b )[1] } @myArray;
      

      use Sort::Key qw( ikeysort );
      
      say for ikeysort { ( split /\|/ )[1] } @myArray;
      

      [这不是一个完整的答案,而是 choroba 的扩展。]

      【讨论】:

      • 感谢 Choroba,我会试用您的代码并回复您。 ikegami,我不打算让数组元素类似于固定长度的记录,但你是对的,现在是这样,我可以移除管道。我忙于编写我的代码,我没有意识到发生了什么。感谢您的提醒。安杰洛
      • 您会发现pack "a3 a3 a3"unpack "a3 a3 a3" 很有用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      • 2022-10-18
      • 2016-11-07
      • 2021-09-23
      相关资源
      最近更新 更多