Choosing grouping of split items

Discussion in 'Perl Misc' started by fishfry, Feb 15, 2004.

  1. fishfry

    fishfry Guest

    If I have

    $text = 'abc - def - ghi - jkl";

    then

    @tokens = split(/-/, $text, 3);

    splits the line into abc, def, ghi - jkl (ignoring leading and trailing
    spaces).

    I have an application where there may be 3 or 4 items separated by '-'
    but if there are 4, I want them returned as abc - def, ghi, and jkl.

    Is there a one-liner for that?
     
    fishfry, Feb 15, 2004
    #1
    1. Advertising

  2. fishfry

    Juha Laiho Guest

    fishfry <> said:
    >If I have
    >
    > $text = 'abc - def - ghi - jkl";
    >
    >then
    >
    > @tokens = split(/-/, $text, 3);
    >
    >splits the line into abc, def, ghi - jkl (ignoring leading and trailing
    >spaces).
    >
    >I have an application where there may be 3 or 4 items separated by '-'
    >but if there are 4, I want them returned as abc - def, ghi, and jkl.
    >
    >Is there a one-liner for that?


    I don't understand the magic of one-lining "everything"; write code as
    it fits nicely. Of course, Perl golf is a different issue (writing code
    to accomplish a given task with a minimal amount of characters).

    As to how I'd solve your problem would be split the data, then join
    the first two fields if the split resulted in 4 fields. Alternative
    would be to write a regular expression that always returns 3 fields;
    something like
    /(.*)\s+-\s+([^-]*)\s+-\s+(.*)/
    might be close to your needs. Whether this is faster or slower than
    splitting and recombining I don't know -- but that you can find out
    with the benchmarking modules.
    --
    Wolf a.k.a. Juha Laiho Espoo, Finland
    (GC 3.0) GIT d- s+: a C++ ULSH++++$ P++@ L+++ E- W+$@ N++ !K w !O !M V
    PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
    "...cancel my subscription to the resurrection!" (Jim Morrison)
     
    Juha Laiho, Feb 15, 2004
    #2
    1. Advertising

  3. fishfry

    Anno Siegel Guest

    fishfry <> wrote in comp.lang.perl.misc:
    > If I have
    >
    > $text = 'abc - def - ghi - jkl";
    >
    > then
    >
    > @tokens = split(/-/, $text, 3);
    >
    > splits the line into abc, def, ghi - jkl (ignoring leading and trailing
    > spaces).
    >
    > I have an application where there may be 3 or 4 items separated by '-'
    > but if there are 4, I want them returned as abc - def, ghi, and jkl.
    >
    > Is there a one-liner for that?


    You can force almost everything into a single statement, the question is
    if you want to. Here is one way:

    my @tokens = reverse map scalar reverse, split /-/, reverse( $str), 3;

    How long does it take to find out what this does? And how long for a
    plain two-statement procedure:

    my @tokens = split /-/, $str;
    @tokens = ( "$tokens[ 0]-$tokens[ 1]", @tokens[ 2 .. $#tokens]) if
    @tokens > 3;

    Anno
     
    Anno Siegel, Feb 15, 2004
    #3
  4. fishfry

    Anno Siegel Guest

    fishfry <> wrote in comp.lang.perl.misc:
    > If I have
    >
    > $text = 'abc - def - ghi - jkl";
    >
    > then
    >
    > @tokens = split(/-/, $text, 3);
    >
    > splits the line into abc, def, ghi - jkl (ignoring leading and trailing
    > spaces).
    >
    > I have an application where there may be 3 or 4 items separated by '-'
    > but if there are 4, I want them returned as abc - def, ghi, and jkl.
    >
    > Is there a one-liner for that?


    You can force almost everything into a single statement, the question is
    if you want to. Here is one way:

    my @tokens = reverse map scalar reverse, split /-/, reverse( $str), 3;

    How long does it take to find out what this does? And how long for a
    plain two-statement procedure?

    my @tokens = split /-/, $str;
    @tokens = ( "$tokens[ 0]-$tokens[ 1]", @tokens[ 2 .. $#tokens]) if
    @tokens > 3;

    Anno
     
    Anno Siegel, Feb 15, 2004
    #4
  5. fishfry

    Jay Tilton Guest

    fishfry <> wrote:

    : If I have
    :
    : $text = 'abc - def - ghi - jkl";
    :
    : then
    :
    : @tokens = split(/-/, $text, 3);
    :
    : splits the line into abc, def, ghi - jkl (ignoring leading and trailing
    : spaces).
    :
    : I have an application where there may be 3 or 4 items separated by '-'
    : but if there are 4, I want them returned as abc - def, ghi, and jkl.

    What did you try?

    Split the string and rejoin whatever fields you want to be together.

    my @tokens = split /-/, $text;
    unshift @tokens, join '-', splice @tokens,0,-2;

    : Is there a one-liner for that?

    If that's what really turns you on.

    my @tokens = map scalar reverse, reverse split(/-/, reverse($text), 3);

    Yuck. Stick with the two-liner.

    Odd. I don't see anywhere in the documentation that says scalar reverse()
    defaults to acting on $_ when no argument is supplied, but it evidently
    does.
     
    Jay Tilton, Feb 15, 2004
    #5
  6. fishfry

    Uri Guttman Guest

    >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    AS> my @tokens = split /-/, $str;
    AS> @tokens = ( "$tokens[ 0]-$tokens[ 1]", @tokens[ 2 .. $#tokens]) if
    AS> @tokens > 3;

    blech!

    $tokens[0] .= '-' . splice( @tokens, 1, 1 ) if @tokens > 3;

    or

    splice( @tokens, 0, 2 ) = join '-', splice( @tokens, 1, 1 )
    if @tokens > 3;

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Feb 15, 2004
    #6
  7. fishfry

    Anno Siegel Guest

    Uri Guttman <> wrote in comp.lang.perl.misc:
    > >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    >
    > AS> my @tokens = split /-/, $str;
    > AS> @tokens = ( "$tokens[ 0]-$tokens[ 1]", @tokens[ 2 .. $#tokens]) if
    > AS> @tokens > 3;
    >
    > blech!


    Agreed.

    > $tokens[0] .= '-' . splice( @tokens, 1, 1 ) if @tokens > 3;


    Much better.

    > or
    >
    > splice( @tokens, 0, 2 ) = join '-', splice( @tokens, 1, 1 )
    > if @tokens > 3;


    That's splice( @tokens, ...) twice in a single statement.

    Anno
     
    Anno Siegel, Feb 15, 2004
    #7
  8. fishfry

    Uri Guttman Guest

    >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    AS> Uri Guttman <> wrote in comp.lang.perl.misc:
    >> >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    >>

    AS> my @tokens = split /-/, $str;
    AS> @tokens = ( "$tokens[ 0]-$tokens[ 1]", @tokens[ 2 .. $#tokens]) if
    AS> @tokens > 3;
    >>
    >> blech!


    AS> Agreed.

    >> $tokens[0] .= '-' . splice( @tokens, 1, 1 ) if @tokens > 3;


    AS> Much better.

    >> or
    >>
    >> splice( @tokens, 0, 2 ) = join '-', splice( @tokens, 1, 1 )
    >> if @tokens > 3;


    AS> That's splice( @tokens, ...) twice in a single statement.

    true. i thought it was kinda cute but not optimal. how about this
    variant:

    $tokens[0] = join '-', shift @tokens, splice( @tokens, 1, 1 ) ;

    again it has @tokens twice. :(

    oh well. i have other fish to fry.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Feb 16, 2004
    #8
  9. fishfry wrote:
    >
    > If I have
    >
    > $text = 'abc - def - ghi - jkl";
    >
    > then
    >
    > @tokens = split(/-/, $text, 3);
    >
    > splits the line into abc, def, ghi - jkl (ignoring leading and trailing
    > spaces).
    >
    > I have an application where there may be 3 or 4 items separated by '-'
    > but if there are 4, I want them returned as abc - def, ghi, and jkl.
    >
    > Is there a one-liner for that?


    $ perl -le'
    $text = "abc - def - ghi - jkl";
    @tokens = $text =~ /(.+)-(.+)-(.+)/;
    print for @tokens;
    '
    abc - def
    ghi
    jkl



    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Feb 16, 2004
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gilles Kuhn
    Replies:
    0
    Views:
    441
    Gilles Kuhn
    Sep 15, 2003
  2. Hvid Hat
    Replies:
    6
    Views:
    441
    Pavel Lepin
    Mar 7, 2008
  3. maury

    Grouping items in checkboxlist

    maury, Apr 17, 2011, in forum: ASP .Net
    Replies:
    0
    Views:
    785
    maury
    Apr 17, 2011
  4. barjunk

    grouping and split

    barjunk, Jul 4, 2007, in forum: Ruby
    Replies:
    7
    Views:
    117
    barjunk
    Jul 11, 2007
  5. AcCeSsDeNiEd

    Grouping like items together

    AcCeSsDeNiEd, Nov 15, 2005, in forum: Perl Misc
    Replies:
    9
    Views:
    189
    AcCeSsDeNiEd
    Nov 17, 2005
Loading...

Share This Page