1

I used the below code to sort values and display it as a dropdown in a Perl form page And I need to display a certain value always at the top of the sorted list, how to do that?

 values= [sort {$a<=>$b and $orig->{$a} cmp $orig->{$b}} keys  %$orig] 

I tried this too,not working with me for some reason

values= [sort {if ($a eq 'somevalue') { return 1; }
elsif ($b eq 'somevalue') { return -1; }
else { return {$a<=>$b and $orig->{$a} cmp $orig->{$b}} keys  %$orig ;} }] 

Any help?

AnFi
  • 10,493
  • 3
  • 23
  • 47
  • So the keys of `$orig` are numbers (that you compare with `<=>`) and the values are strings (that you compare with `cmp`)? That's not implausible, but it is unusual. – mob Oct 19 '17 at 14:17

3 Answers3

0

slice the 1st element before sort than put it back before display, like

my @foo = ( header, 4, 5, 6 );
$bar = shift(@foo);

# sort it or do what you want

unshift(@foo,$bar);

print @foo, "\n";
V-Mark
  • 176
  • 5
  • That' would be fine if I want to display the first value of the hash ref.Unfortunately I don't know at what position or index my value is there .I only know it's value i.e,"somevalue" and I am sorting and printing in a form feild bdw so I can't explicitly use print here!! – KnowNothing Oct 19 '17 at 08:00
  • Oh. I was sure you need the header at the top, as you mentioned: "certain value always at the top of the sorted list" ... and I assumed (incorrectly) it is originally in the top. – V-Mark Oct 19 '17 at 08:50
  • yes,I do the need the header at the top and even I wouldn't know where it would be..Refer the above answer and Do you think that you can modify that answer according to my question and provide me a working solution? – KnowNothing Oct 19 '17 at 09:09
0

You can sort $special value like the lowest using (($b eq $special) - ($a eq $special)) as the first link in "sORt chain":

my $special = "somevalue";
sort { (($b eq $special) - ($a eq $special)) || 
       $a<=>$b || $orig->{$a} cmp $orig->{$b} } keys  %$orig;

(($b eq $special) - ($a eq $special)) returns:
0 when $a and $b are special [$a is equal $b]
-1 when $a is special and $b is not [$a less than $b]
+1 when $b is special and $a is not [$a greater than $b]
0 when both $a and $b are not special [$a is equal $b]

When it produces 0 next links in the sORt chain are queried.

AnFi
  • 10,493
  • 3
  • 23
  • 47
  • It's almost working,But the problem is it's messing the sort order which I want. [sort{$a<=>$b and $orig->{$a} cmp $orig->{$b}} keys %$orig ] This is the sort order i want with some value at the top.But your answer is giving that somevalue at the top with ASCII sorting – KnowNothing Oct 19 '17 at 09:02
  • Could you provide sample hash with sorting output you expect? – AnFi Oct 19 '17 at 09:35
0

Assuming your hash contains only non-negative keys, you can sort the header values as if they were -∞ which will sort before anything else, but will be equal to itself

sort {
    my ($aa, $bb) = map { $_ eq $special ? -Inf : $_ } $a, $b;
    $aa <=> $bb and $orig->{$aa} cmp $orig->{$bb};
} keys %$orig;
Borodin
  • 126,100
  • 9
  • 70
  • 144