in reply to Turning a hash into a line of links

Hi guys. Thanks again for all the comments. While I was playing with this, I had the "old way" (with the extra pipe) and the "new way" printing at the same time, and the top line was longer than the second, and it looked cool. So I decided to try to divise a programmatic way to split the line into two, with the top part never having less elements than the second. My algorithm was to take the final string, count the number of pipes in it, and then turn the "middle" one (and, if no clear "middle," then skew towards later in the string) into a br tag. Here's what I came up with:
my $homes=join(" |",@la); #print $homes; my @pipes; my $pos; while ($homes =~ m/\|/g){ push @pipes, pos($homes)-1; } my $numps=scalar(@pipes); my $ptr= $numps-int($numps/2); #no ceil() function in perl substr($homes,$pipes[$ptr],1,"<br>");#not catching rv--is that bad? print $homes;
I know there are probably better ways, but I kind of had fun figuring this out in a way that's flexible if sections are added/subtracted.

I like computer programming because it's like Legos for the mind.

Replies are listed 'Best First'.
Re^2: Turning a hash into a line of links
by johngg (Canon) on Dec 13, 2006 at 16:08 UTC
    A slightly different, but not necessarily better, way would be to count the pipes using tr, like this

    my $numps = ($homes =~ tr{|}{});

    and then find the "middle" one's position by using index in a loop

    my $middle = int($numps / 2) + 1; my $pos = -1; my $found = 0; while (1) { $pos = index $homes, q{|}, $pos; last if ++ $found == $middle; $pos ++; } substr $homes, $pos, 1, q{<BR>};

    As you say, it is fun trying these things out. As for checking return values, I should perhaps check that index doesn't return -1 and that substr does return the pipe that I think I'm replacing; if this was production code I probably would :)

    Cheers,

    JohnGG

      tr//--Now there's another element of perl with which I am not very familiar. When I was devising my plan, I decided that I wanted to only loop through/traverse the string once, thus the array of positions of the pipes. Does tr not loop through the string? I'll have to look that up. I was focused on the thought that I will have to loop through the string once to count all the pipes; might as well save the positions while I am there so I don't have to go back through to "find" the middle one. Yeah I had to use the number of elements in the @pipes array to do some funky arithmetic, but only one time through the string.

      I've seen the q{} contruct more than once now. Do you guys use a lot of strings that contain embedded quotes? What are the relative merits of q{hi} vs 'hi'?

      Thanks,
      Terrence

      UPDATE: I figured out what tr/// does. I kept bouncing back and forth between tr///, which says "same as y///" and y///, which says "same as tr///." Finally saw the part that says "see perlop." Thanks.


      I like computer programming because it's like Legos for the mind.
        I have hardly ever used tr but I bumped into it the other day when looking something else up in the Camel Book. I thought that it could be useful for just the thing you are doing. It would be interesting to benchmark the various ways of counting characters or strings within strings.

        Regarding q{} and qq{}, I am from a *nix background and had never had any problem with normal single- and double-quotes. Then I started trying to do one-liners under MS Windoze and struggled. The quoting operators made it all work nicely and since then, to avoid having to think where I am, I have got into the habit of using them all the time. I don't think that there is any particular merit either way other than normal quotes are widely familiar and take fewer keystrokes, quoting operators do the right thing at the DOS prompt.

        Cheers,

        JohnGG