0

I have an array with sequences as shown below in it

my @a = qw(AAAA CGTGATG CGTGATTTGG);

I want to print out the sequence which is longest in the length using perl. So output should be

CGTGATTTGG

#!/usr/bin/perl-w
use strict;
use warnings;
use List::Util qw( min max );

my %hash = ();
my @a = qw(AAAA CGTGATG CGTGATTTGG);

foreach(@a){
    print join("\t",$_,length($_)),"\n";
}

Which prints out

AAAA    4
CGTGATG 7
CGTGATTTGG  10

I just want to print the seq with the longest string that is 10

How can I do it

Thanks

user3138373
  • 519
  • 1
  • 6
  • 18

3 Answers3

2

A simple solution that returns the first of the longest strings:

use List::Util qw( reduce );

my $longest = reduce { length($a) >= length($b) ? $a : $b } @a;

A simple solution that returns the all of the longest strings:

use List::Util qw( max );

my $max_len = max map { length($_) } @a;
my @longests = grep { length($_) == $max_len } @a;
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • This is the best answer for this specific question because strictly taking the longest sequence will lead to unexpected results. – SES Mar 25 '16 at 16:24
0

Here is the fastest from the previous post on this topic:

sub longest {
    my $max = -1;
    my $max_ref;
    for (@_) {
        if (length > $max) {  # no temp variable, length() twice is faster
            $max = length;
            $max_ref = \$_;   # avoid any copying
        }
    }
    $$max_ref
}
Community
  • 1
  • 1
dawg
  • 98,345
  • 23
  • 131
  • 206
  • 1
    Note that this only finds one of the longest (the first one) – ikegami Mar 23 '16 at 21:49
  • The OP stated: **"I just want to print the seq with the longest string"** This does that. – dawg Mar 23 '16 at 23:18
  • Again, only if there's only one string that's longest. If there's more than one sing tied for longest, it returns **one of the longest** instead. – ikegami Mar 23 '16 at 23:20
  • 1
    I'm not saying your solution is wrong; I'm just making a note of how it behaves in the situation the OP forgot to cover. – ikegami Mar 23 '16 at 23:25
-1

Use a Schwartzian transform:

use strict;
use warnings;
use v5.10;

my @sorted = map  { $_->[0] }
             sort { $a->[1] <=> $b->[1] }
             map  { [$_, length($_)] }
             qw(AAAA CGTGATG CGTGATTTGG);

say $sorted[-1];
say pop(@sorted);
Matt Jacob
  • 6,503
  • 2
  • 24
  • 27
  • I'm not sure that ST helps here. It only helps if time it takes to find the length of a string the second time is longer than the time it takes to do `->[1]` (and that's not even counting ST's overhead). It might actually make things slower. – ikegami Mar 23 '16 at 20:56
  • This solution doesn't scale well. It's O(N log N), while there exists an O(N) solution. – ikegami Mar 23 '16 at 20:57