good chemistry is complicated,and a little bit messy -LW PerlMonks

### Comment on

 Need Help??

this meditation describes an arbitrary problem to be solved in different ways and in different languages.

The Problem

Given a list of strings, for example ("a", "bb", "c", "d", "e", "f", "g", "h"), and a chunksize, for example 3, write a subroutine to return a multi-line string, for example:

```a bb c
d e f
g h
The output string must contain a single space between each array element and a newline every chunksize items. Note that no trailing space is permitted on any line and the last line must be properly newline-terminated.

Perl

Here was my first Perl attempt:

```use strict;
use warnings;

sub chunk_array {
my (\$n, @vals) = @_;
my \$str;
my \$i = 0;
for my \$v (@vals) {
++\$i;
\$str .= \$v . ( (\$i % \$n) ? " " : "\n" );
}
substr(\$str, -1, 1) = "\n";
return \$str;
}

my \$v1 = chunk_array(3, "a", "bb", "c", "d", "e", "f", "g", "h");
\$v1 eq "a bb c\nd e f\ng h\n" or die "error: '\$v1'\n";
print \$v1;

my \$v2 = chunk_array(3, "a", "bb", "c", "d", "e", "f");
\$v2 eq "a bb c\nd e f\n" or die "error: '\$v2'\n";
print \$v2;

I trust this initial solution will clarify the problem specification.

Being dissatisfied with this ugly first attempt, I next took at a look at the core List::Util and the non-core List::MoreUtils modules, writing two different solutions using List::MoreUtils, one using natatime, the other part, as shown below:

```use List::MoreUtils qw(part natatime);

sub chunk_array {
my (\$n, @vals) = @_;
my \$str;
my \$iter = natatime(\$n, @vals);
while ( my @line = \$iter->() ) {
\$str .= join(" ", @line) . "\n";
}
return \$str;
}

sub chunk_array {
my (\$n, @vals) = @_;
my \$i = 0;
return join "", map { join(" ", @\$_)."\n" } part { \$i++/\$n } @vals
+;
}

Python

For cheap thrills, I hacked out a Python itertools-based solution.

```from itertools import *

def group(n, iterable):
args = [iter(iterable)] * n
return izip_longest(*args)

def chunk_array(n, vals):
return "".join(" ".join(x for x in i if x!=None)+"\n" for i in group
+(n, vals))

Discussion

I've derived little enjoyment so far from any of my solutions and accordingly encourage you to show us a more elegant way to solve this simple problem.

Please feel free to contribute more Perl solutions or a solution in any language you fancy. I'm especially eager to admire a Perl 6 solution.

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

• Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
• Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
• Read Where should I post X? if you're not absolutely sure you're posting in the right place.
• Posts may use any of the Perl Monks Approved HTML tags:
a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
• You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
 For: Use: & & < < > > [ [ ] ]
• Link using PerlMonks shortcuts! What shortcuts can I use for linking?

Create A New User
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (9)
As of 2017-12-16 10:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
What programming language do you hate the most?

Results (450 votes). Check out past polls.

Notices?