in reply to Re: Comparing hashes and arrays
in thread Comparing hashes and arrays

That is probably a pretty good start on a golf answer. I do wonder however whether it was at all useful to a user who asks this level of question. Perhaps you could explain how it works to the inquiring monk, that would make it more valueable.

Update I don't believe this returns the right result either. I am still checking out why, will update shortly.

Update 2:
The solution you presented fails to produce the requested 999 result in the case of the missing entry. It also fails to capture the negative value, -7.9.

I will break down the provided solution so the questioner can perhaps understand what is going on better.

map{ # map is a way of building a loop # map returns a list of the resulting values. # this use of map makes no use of the returned list # which is often considered bad form, however when # golfing it can be useful for shortening your code. /(\S+)\s+([\d.]*)/; # this is a regular expression # (\S+) says to grab 1 or more # non-white-space characters, # the result captured to $1 # \s+ says to grab 1 or more # white-space characters # ([\d.]*) says to grab either # digits (\d) or a period (.) # 0 or more times. # this will be captured to $2 $2 # This is a a ternary operator # A sometimes useful way of # writing an if-else statement. # This says "if $2" ? ( $a{$1} = $2 ) # then set $a{$1} to $2 : ( $a{$1} = 999 ) # else set $a{$1} to 999 }<FILE>; # the lines read from <FILE> will be used # as input to the map, as $_ map{push(@result,$a{$_})}@order; # again a map, taking the order array and pushing the # related values from the $a hash into @results # giving you the ordered numbers.
This code has two errors, and one potential gotcha.

The resulting fixed code...

map{/(\S+)\s+(-?[\d.]+)/;$a{$1}=$2?$2:''}<DATA>; map{push(@result,defined $a{$_} ? $a{$_} : 999)}@order;

Perhaps we should call golf-on?

Replies are listed 'Best First'.
(bbfu) (golf-esqe?) Re3: Comparing hashes and arrays
by bbfu (Curate) on Sep 06, 2001 at 21:37 UTC

    $2 ? ... will give the wrong result [...] This can be fixed using $2 ne ''

    Well, it seems to me from the original post that the file will always have both columns; if the match doesn't succeed then the line is not valid and (maybe?) shouldn't be considered.

    The code becomes (note that map in void context is almost always considerably slower than for):

    # assuming @i = map "name$_" 1..5 /(\S+)\s+(-?\d+(?:.\d+)?)/and$a{$1}=$2 for<DATA>; push@o,exists$a{$_}?$a{$_}:999 for@i;

    Remember, this simply ignores lines in the file that don't have both columns. It also ignores a second decimal (and everything after) in the second column. It all depends on how lenient we want to be of bad data.

    bbfu
    Seasons don't fear The Reaper.
    Nor do the wind, the sun, and the rain.
    We can be like they are.

Re: Re: Re: Comparing hashes and arrays
by Anarion (Hermit) on Sep 06, 2001 at 22:02 UTC
    Your code has now an error, that mine has not, if the second value is null.
    /(\S+)\s+(-?[\d.]+)/;
    If the second value is null the re doesn't match and $2 is the one of the match before.
    Update:
    Sorry i dont read that bbfu has fixed it adding ?

    $anarion=\$anarion;

    s==q^QBY_^=,$_^=$[x7,print

      Did you actually run it before you told me it was wrong?

      If the second value is null as in something like

      __DATA__ name1 4.5 name3 name5 6.5 name4 -7.9 name6 3.2
      The the entire pattern will not match since the second value is required according to the regex. Also, a simple test of adding a print statement during the match will educate you that the $1 and $2 are not carried over.
      Run this to see...
      my @order = qw(name1 name2 name3 name4 name5 name6); map{/(\S+)\s+(-?[\d.]+)/;$a{$1}=$2?$2:'';print "$1 -- $2 \n";}<DATA>; map{push(@result,defined $a{$_} ? $a{$_} : 999)}@order; print join("\n", @result),"\n"; __DATA__ name1 4.5 name3 name5 6.5 name4 -7.9 name6 3.2
      Notice the added print line will show you that $1 and $2 are empty, not the previous values.

      So, to conclude -- actually running it would have shown you that there was no error.