Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I have an array like this:
@array=('Currency','USD','Asset','Equity','Country','USA');
and i only want to join on every other element. In other words, I want I string that looks like: 'USD_Equity_USA'. Can anyone come up with something better than
for (my $i=0; $i<@array; $i+=2) { $desc .= "$array->[$i+1]_"; } chop($desc);
thanks, Michael

Replies are listed 'Best First'.
Re: selective join
by dws (Chancellor) on Sep 24, 2003 at 17:00 UTC
    Hi monks, I have an array like this:

    Are you really sure you have an array? It looks to me like what you have is a hash disguised as an array. That is,

    my %record = ( Currency => 'USD', Asset => 'Equity', Country => 'USA' );
    If that's the case, and if the key structure is similar across multiple such records, your code would be significantly clearer if you write something like
    my $desc = join '_', @record{qw(Current Asset Country)};
    (This assumes that your readers understand hash slices.)

      <movie_critic_mode>   Insightful!   Beautiful!   "I grinned broadly"   </movie_critic_mode>

      No, really, now that you point it out, it may _be_ a flattened hash AM's playing with.   And you point out a solution using hash slices because:

      • using keys %record would be wrong as you can't guarantee the order that the keys will be returned.
      • there may be other hash keys that he doesn't want to use
Re: selective join
by BrowserUk (Patriarch) on Sep 24, 2003 at 15:52 UTC

    Use an array slice...

    my $desc = join'', @array[1,3,5];

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

Re: selective join
by blokhead (Monsignor) on Sep 24, 2003 at 15:58 UTC
    If you always know the number of things in @array, it's probably just best to write the odd indices explicitly and use an array slice:
    my $desc = join "_" => @array[1,3,5];
    If @array has a variable size, you'll have to figure out the odd indices on the fly:
    my $desc = join "_" => @array[ grep { $_ % 2 } 0 .. $#array ];
    You can also get odd indices this way too, but not as elegantly as with grep:
    my $desc = join "_" => @array[ map { 2*$_ + 1 } 0 .. (@array/2)-1 ];

    blokhead

Re: selective join
by dragonchild (Archbishop) on Sep 24, 2003 at 15:59 UTC
    Try thinking in steps.
    1. You have a list of stuff.
    2. You want to get a sub-list of specific stuff.
    3. You want to perform some action on that sub-list.
    ############################## # This code has been tested. # ############################## # Step 1 - Get your starting list my @main_list= ('Currency','USD','Asset','Equity','Country','USA'); # Step 2 - Generate the sub-list my @sublist_indices = grep { !(($_ + 1) % 2) } (0 .. $#main_list); my @sublist = @main_list[@sublist_indices]; # Step 3 - Do the action(s) on the sub-list my $string = join '_', @sublist; print "'$string'\n";

    Because you're dealing with every other element, some people will suggest using a hash. But, a hash has two problems:

    • A hash is unordered.
    • A hash only works with every other item.

    The solution I (and others) have above will work for any rule for determining the sublist indices.

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      Nice explaination ++
Re: selective join
by Abigail-II (Bishop) on Sep 24, 2003 at 16:08 UTC
    my $i = 1; my $desc = join "_" => grep {$i = !$i} @array;

    Abigail

Re: selective join
by Limbic~Region (Chancellor) on Sep 24, 2003 at 15:48 UTC
    Anonymous Monk,
    I am sure there is a more elegant way than this and that some other uber cool monk will provide it, but here goes:
    #!/usr/bin/perl -w use strict; my @array = qw(0 1 2 3 4 5 6 7 8); print join '_' , grep length, map {$array[$_] if $_ % 2 == 1} (0 .. $# +array);

    Cheers - L~R

    Update: If you know the number of elements in the array, don't use this method - use BrowserUk's solution