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

I'm trying to print to file a tab delimited array I've just sorted. Linebreaks are elements in the array that signify new lines as new entries. The problem is that the Join function adds a tab to every element, including \n, which presents itself at the beginning of every line. I've written the following test snippet in an attempt to cut the tab following a \n out, but for the life of me it will not work. I humbly ask for your wisdom, good monks.

use warnings; use strict; open (outputFile, ">", "TestNew.txt"); my @infoArray = (1, 2, 3, 4, 5, '\n', 6, 7, 8, 9, 10, '\n'); my $x = 0; my $test = "\n"; my @finalArray = join ("\t", @infoArray); foreach (@finalArray) { if ($_ eq $test) { splice (@finalArray, $x + 1, 1); } else { $x = $x + 1; } } print outputFile @finalArray;

Replies are listed 'Best First'.
Re: Splicing the next element in an array
by zwon (Abbot) on Apr 08, 2014 at 16:04 UTC
    Your @finalArray contains just one element. Also, '\n' and "\n" are not the same.
    use 5.010; use strict; use warnings; my @infoArray = ( 1, 2, 3, 4, 5, "\n", 6, 7, 8, 9, 10, "\n" ); my @line; for (@infoArray) { if ( $_ eq "\n" ) { say join "\t", @line; @line = (); } else { push @line, $_; } }
      This made much more sense, and worked on my input file. Thank you.
Re: Splicing the next element in an array
by Laurent_R (Canon) on Apr 08, 2014 at 16:46 UTC
    Possibly with the map function:
    my @infoArray = (1, 2, 3, 4, 5, "\n", 6, 7, 8, 9, 10, "\n"); my @final_array = map { $_ eq "\n" ? $_ : "$_\t"} @infoArray; # now print @final_array, for example: print join '', @final_array;
    which prints:
    1 2 3 4 5 6 7 8 9 10
    Or you could print directly the output of map:
    print join '', map { $_ eq "\n" ? $_ : "$_\t"} (1, 2, 3, 4, 5, "\n", + 6, 7, 8, 9, 10, "\n");
    giving the same output.

    Update (Apr 08, 2014 at 17:15 UTC): added the output and the one-line final piece of code (did not have Perl on my tab when I wrote the original post while in public transportation).

Re: Splicing the next element in an array
by AnomalousMonk (Archbishop) on Apr 08, 2014 at 17:44 UTC

    Or else do a fix-up on the final string after it's all been joined together:

    c:\@Work\Perl\monks>perl -wMstrict -le "my @infoArray = (1, 2, 3, 4, 5, qq{\n}, 6, 7, 8, 9, 10, qq{\n}); ;; my $finalString = join qq{\t}, @infoArray; ;; $finalString =~ s{ ^ \t }''xmsg; print qq{'$finalString'}; " '1 2 3 4 5 6 7 8 9 10 '
Re: Splicing the next element in an array
by kcott (Archbishop) on Apr 08, 2014 at 21:15 UTC

    Here's how I might have done that. I've accounted for elements with embedded and terminal newlines. This also prints a final newline if the last element didn't end with one.

    #!/usr/bin/env perl use strict; use warnings; my $delimiter = '<TAB>'; my @info = (1 .. 5, "\n", 6 .. 10, "\n", "A\nB", "C\n", 'D', 'end'); print /\n$/ ? $_ : "$_$delimiter" for @info[0 .. $#info - 1]; print $info[-1] =~ /\n$/ ? $info[-1] : "$info[-1]\n";

    Output:

    1<TAB>2<TAB>3<TAB>4<TAB>5<TAB> 6<TAB>7<TAB>8<TAB>9<TAB>10<TAB> A B<TAB>C D<TAB>end

    [Obviously, <TAB> is just used as a visual aid: change '<TAB>' to "\t" in the real application.]

    Update: Changed "'<TAB>' to "\n"" to "'<TAB>' to "\t"". Thanks to Laurent_R for spotting that.

    -- Ken