splice or split an array

Discussion in 'Perl Misc' started by Peter, Sep 7, 2004.

  1. Peter

    Peter Guest

    Hello,
    I try to split an array into a couple of arrays the same size.

    This is my code and I think its very ugly ;-)

    Does anoyone has a better idea?

    @list =
    ("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"
    ,"18");

    $pack =5;

    $avg = $#list / $pack + 1;

    for(1..$pack+1)
    {
    @newlist = splice(@list,0,$avg) if @list;

    print "@newlist\n";
    }
     
    Peter, Sep 7, 2004
    #1
    1. Advertising

  2. Peter wrote:
    > Hello,
    > I try to split an array into a couple of arrays the same size.


    "A couple" is 2. I think you mean "an arbitrary number".

    On course this is only possible if there are an exact multiple of that
    number of elements in the original array. What do you want to happen if
    this condition doesn't hold? I assume from your code you want the last
    sublist to be short.

    > This is my code and I think its very ugly ;-)


    I don't think it's _very_ ugly. It seems basically right - you use
    splice(@list,0,$sublist_size).

    I would scatter in a few 'my's in appropriate places.

    I'd remove the the redundant 'if @list'. In general you should avoid
    having an if that skips over a bit of code in the condition where the
    bit of code wouldn't do anything at anyhow (unless there is a
    significant performance issue).

    I'd probably use a while rather than a for.

    I'd use more mnemonic variables.


    > Does anoyone has a better idea?
    >
    > @list =
    > ("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"
    > ,"18");
    >
    > $pack =5;
    >
    > $avg = $#list / $pack + 1;
    >
    > for(1..$pack+1)
    > {
    > @newlist = splice(@list,0,$avg) if @list;
    >
    > print "@newlist\n";
    > }


    while( my @newlist = splice(@list,0,$sublist_size)) {
    print "@newlist\n";
    }

    I can't really comment if your calculation is right since we don't know
    your objectives.
     
    Brian McCauley, Sep 7, 2004
    #2
    1. Advertising

  3. Scott Bryce wrote:
    > Peter wrote:
    >
    >> @list =
    >> ("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"
    >> ,"18");

    >
    > Double quotes are neither necessary, nore desireable here.
    >
    > my @list = qw(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18);
    >
    > or
    >
    > my @list = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18);
    >
    > or
    >
    > my @list = (1 .. 18);


    Speaking of unnecessary, the parentheses are not required in the last example.
    :)

    my @list = 1 .. 18;


    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Sep 8, 2004
    #3
  4. Peter

    Anno Siegel Guest

    Peter <> wrote in comp.lang.perl.misc:
    > Hello,
    > I try to split an array into a couple of arrays the same size.
    >
    > This is my code and I think its very ugly ;-)
    >
    > Does anoyone has a better idea?
    >
    > @list =
    > ("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17"
    > ,"18");
    >
    > $pack =5;
    >
    > $avg = $#list / $pack + 1;
    >
    > for(1..$pack+1)
    > {
    > @newlist = splice(@list,0,$avg) if @list;
    >
    > print "@newlist\n";
    > }


    Your loop runs one time too many. It will print the last partial
    list twice. You seem to want $pack sublists, so the loop should
    run over 1 .. $pack.

    Equal sizes are, of course, only possible if $pack divides the length
    of the original list. Your solution, like Brian's proposition, leaves
    the last sublist short. If it matters, the sublist can be made more
    equal than that:

    my @list = 1 .. 18;
    my $pack = 5;

    my @sizes = ( int @list/$pack) x $pack;
    $_ ++ for @sizes[ 0 .. @list % $pack - 1];
    print "@$_\n" for map [ splice @list, 0, $_], @sizes;

    This produces sublists whose sizes differ by at most one. The first
    few (@list % $pack) are longer.

    A similar result, but with the longer lists last, can be obtained
    like this:

    while ( @list ) {
    my @newlist = splice @list, 0, @list/$pack--;
    print "@newlist\n";
    }

    but that one is a little hard to verify. Will it ever divide by zero?
    Also, it destroys not only @list, but also $pack.

    Anno
     
    Anno Siegel, Sep 8, 2004
    #4
    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. Gary Wessle

    split, splice and the like

    Gary Wessle, Aug 3, 2006, in forum: C++
    Replies:
    7
    Views:
    364
    Mark P
    Aug 3, 2006
  2. Ved

    Array in splice

    Ved, Jul 4, 2007, in forum: Perl Misc
    Replies:
    0
    Views:
    133
  3. BrianP
    Replies:
    2
    Views:
    296
  4. Replies:
    1
    Views:
    160
    Richard Cornford
    Jun 26, 2008
  5. dhtml
    Replies:
    18
    Views:
    204
    dhtml
    Aug 23, 2008
Loading...

Share This Page