Schwartzian method

Schwartzian method

am 12.06.2007 18:30:40 von jis

Hi all,

I was reading through UR coloumn by Randal in ww.stonehenge.com. I
cam across the Schwartzian method which I find extremely difficult to
understand even after the explanation given by him.Please help me
understand the concepts.

1)
@data = <>; # read data
foreach (@data) {
($name,$score) = split; # get score
$score{$_} = $score; # record it
}

I guess $_ has the instantaneous data from @data. Am I correct?

2)

@pairs = map {
($name, $score) = split;
[ $_, $score ];
} @data;
What is $_ in the ablove code?
Randal says "I build a two-element anonymous list from the
$score and the original value $_". Can somebody help me to understand
what he means?


3)
print
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [$_, (split)[1] ] }
<>;
What is $_->[0] all about?


regards,
jis

Re: Schwartzian method

am 12.06.2007 19:22:44 von Paul Lalli

On Jun 12, 12:30 pm, jis wrote:

There's really no reason to post three copies of the same message.
One is sufficient.

> I was reading through UR coloumn by Randal in ww.stonehenge.com. I
> cam across the Schwartzian method which I find extremely difficult to
> understand even after the explanation given by him.Please help me
> understand the concepts.
>
> 1)
> @data = <>; # read data

Randal wrote that?! Shame!!

> foreach (@data) {
> ($name,$score) = split; # get score
> $score{$_} = $score; # record it
> }
>
> I guess $_ has the instantaneous data from @data. Am I correct?

Yes. See also, `perldoc perlsyn`. When a foreach loop is not
explicitly given a named variable to use to iterate over the list, the
$_ variable is used automatically.

> 2)
> @pairs = map {
> ($name, $score) = split;
> [ $_, $score ];
> } @data;
> What is $_ in the ablove code?

See also: `perldoc -f map`. The above executes the code within the
block once for each element of @data. The results of each execution
are added to the @pairs array. For each iteration of this execution,
it puts the current value of @data into $_, very much the same way
that the foreach loop above operates.

> Randal says "I build a two-element anonymous list from the
> $score and the original value $_". Can somebody help me to understand
> what he means?

For each element of @data, he is splitting that element on the
whitespace. The results of that split are put into $name and $score.
That's the first line of the map block. The second line is an
anonymous array reference. The first element of this anonymous array
is $_ - which is the current element of @data. The second element of
the anonymous array is the value of $score that was found for this
iteration. That anonymous array reference is then returned from the
block (all Perl blocks return the last value evaluated) and is
therefore added to the @pairs array.

So if @data started out as:
("Paul 100", "John 30", "Mary 15")
then @pairs would be:
( [ "Paul 100", 100], ["John 30", 30"], ["Mary 15", 15] )
That is, @pairs is a transformation of @data, where each element of
@data is now represented as a two element array.

>
> 3)
> print
> map { $_->[0] }
> sort { $a->[1] <=> $b->[1] }
> map { [$_, (split)[1] ] }
> <>;
> What is $_->[0] all about?

You need to read up on references. I suggest `perldoc perlreftut` as
a good starting point. This code takes what is read from <> (which
was represented by @data earlier), maps it to give us our list of
array references (@pairs earlier), then sorts @pairs, and then passes
that sorted list of array references back to map.

Like before, the $_ in the map block represents each subsequent
element of the list that it's iterating over. In this case, each of
those elements is a reference to an anonymous array (because that's
what the bottom map created). $_->[0] is the first element of the
array that $_ references. That is, it is the original line from <>.

Hope this helps,
Paul Lalli