Gaal has already given you good answers, let me amend them with a few
comments

On Tue, Jul 8, 2014 at 10:45 PM, Gaal Yahas <[email protected]> wrote:

>
>
>
> On Tue, Jul 8, 2014 at 9:31 PM, Assaf Gordon <[email protected]>
> wrote:
>
>> Hello,
>>
>
>
>>
>>
>> 2. Given a hash with string-keys and numeric-values, how to return a list
>> of the keys,
>> sorted by the values?
>> e.g
>>   my %h = ( "hello" => 4,
>>             "world" => 1,
>>             "foo" => 2,
>>             "bar" => 3 )
>> return:
>>    ( "world", "foo", "bar", "hello" )
>>
>> I came up with:
>>    my @result =
>>            map { $_->[0] }
>>              sort { $a->[1] <=> $b->[1] }
>>                map { [ $_, $h{$_} ] }
>>                  keys %h;
>>
>> Is there a better way?
>>
>
> This is fine.
>


Fine, but use the Schwartizan transform only if it is really necessary
speed-wise. In this case the following code would be faster,
and certainly more simple:

    my @result = sort { $h{$a} <=> $h{$b} } keys %h;




>
>>
>>
>> 3. How to automatically use the appropriate "cmp" or "<=>" ?
>> I have a function that accepts a list.
>> The list is either all strings, or all numbers.
>> Half-way through, the function needs to sort the list.
>> Is there a simple way to know whether to use "cmp" or "<=>" ?
>>
>> I don't want to duplicate code with two functions, and would prefer to
>> avoid adding an extra parameter to the function telling it if these are
>> numbers or strings.
>>
>
> sub untested_solution {
>   my @input = @_;
>   return if @input == 0;
>   # We were promised the input is at least consistent, so sniff the first
> element.
>   my $cmp = looks_like_a_number($input[0]) ?
>       sub { $a <=> $b } : sub { $a cmp $b };
>   return sort $cmp, @input;
> }
>
> # You could find a better implementation of this. Probably mucking around
> the C API
> # there's even a "correct" (more or less) way, but it sounds like you
> can't use modules.
> sub looks_like_a_number {
>   my ($x) = @_;
>   no warnings;
>   return $x eq $x+0;
> }
>
>
>

Or you could use the looks_like_number function of  Scalar::Util  that has
been standard modules since 5.8
http://corelist.rpee.be/m/Scalar::Util and it seems the function was
already available in 5.8.8.
http://perldoc.perl.org/5.8.8/Scalar/Util.html (you might want to check
version 5.8.0 yourself)

Gabor
_______________________________________________
Perl mailing list
[email protected]
http://mail.perl.org.il/mailman/listinfo/perl

Reply via email to