yvi (
yvi) wrote in
dw_dev_training2009-11-24 12:30 pm
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
![[site community profile]](https://www.dreamwidth.org/img/comm_staff.png)
Entry tags:
Need some help: tag sorting
Since
denise asked so nicely, I might put up some questions during the next few days.
I apologize if this description is messy - I can be very bad at explaining these things.
One of the bugs I am currently stuck on is http://bugs.dwscoalition.org/show_bug.cgi?id=2012 use a tag list not a tag cloud on the subscription filter interface The goal is to change th tag cloud here: http://www.dreamwidth.org/manage/subscriptions/filters to an alphabetically sorted tag list with usage numbers. Despite my complete inability with javaScript, I managed the 'tag list with usage numbers' part fine. I am, however, stuck on the alphabetically sorted part.
It looks like sorting the tags before they reach that point might be the way to go and htdocs/tools/endpoints/general.bml might be the key to that.
get_usertags returns a "Hashref; key being tag id, value being a large hashref". It looks like hashes in perl can be sorted - is there a way to sort this hash by name? I imagine this structure looks something like:
hash{id1} = { 'name' => name1,
'usage' => usage1,
...}
hash{id2} = { 'name' => name2,
'usage' => usage2,
...}
and now I need to sort the ids by name.
There is some sorting going on in cgi-bin/LJ/S2/TagPage.pm:
But that returns a sorted array.
Any ideas?
EDIT: Okay, looks like I either need to sort the ids by name and then return both the hashref and the array and handle that in the JavaScrript portion or sort in htdocs/js/subfilters.js itself. The relevant code is in function cfUpdateTags( data ), the
![[staff profile]](https://www.dreamwidth.org/img/silk/identity/user_staff.png)
I apologize if this description is messy - I can be very bad at explaining these things.
One of the bugs I am currently stuck on is http://bugs.dwscoalition.org/show_bug.cgi?id=2012 use a tag list not a tag cloud on the subscription filter interface The goal is to change th tag cloud here: http://www.dreamwidth.org/manage/subscriptions/filters to an alphabetically sorted tag list with usage numbers. Despite my complete inability with javaScript, I managed the 'tag list with usage numbers' part fine. I am, however, stuck on the alphabetically sorted part.
It looks like sorting the tags before they reach that point might be the way to go and htdocs/tools/endpoints/general.bml might be the key to that.
} elsif ( $mode eq 'list_tags' ) { $ret{tags} = LJ::Tags::get_usertags( $u, { remote => $remote } );
get_usertags returns a "Hashref; key being tag id, value being a large hashref". It looks like hashes in perl can be sorted - is there a way to sort this hash by name? I imagine this structure looks something like:
hash{id1} = { 'name' => name1,
'usage' => usage1,
...}
hash{id2} = { 'name' => name2,
'usage' => usage2,
...}
and now I need to sort the ids by name.
There is some sorting going on in cgi-bin/LJ/S2/TagPage.pm:
my $tags = LJ::Tags::get_usertags($u, { remote => $remote }); foreach my $kwid (keys %{$tags}) { # only show tags for display next unless $tags->{$kwid}->{display}; push @taglist, LJ::S2::TagDetail($u, $kwid => $tags->{$kwid}); } @taglist = sort { $a->{name} cmp $b->{name} } @taglist;
But that returns a sorted array.
Any ideas?
EDIT: Okay, looks like I either need to sort the ids by name and then return both the hashref and the array and handle that in the JavaScrript portion or sort in htdocs/js/subfilters.js itself. The relevant code is in function cfUpdateTags( data ), the
for ( id in data.tags ) {
loop would need to be run through in order of data.tags[id].name
.
no subject
Not as such. What people usually do is get the list of keys of that hash, and sort the list; then use the sorted list of keys to access the corresponding hash entry. (So something like
for $key (sort keys %hash) { $value = $hash{$key}; do_something_with($value) }
.) (BTW,for
is an alias forforeach
, so you could also go withforeach my $key (sort keys %hash) { ... }
.) (And if you have a hashref, then something likefor $key (sort keys %{$hashref}) { $value = $hashref->{$key}; do_something_with($value) }
.)I imagine this structure looks something like:
Yes, though probably with
hash->{id1}
rather thanhash{id1}
since you have a hashref rather than a hash.But that returns a sorted array.
Yes, an array of objects (whatever
LJ::S2::TagDetail
returns), with those objects sorted by their names. Are those unsuitable for your purpose?no subject
I tried it and the javaScript portion refuses to take it - I don't know enough JS to change that part - though if anyone does, they can be my guest :)
since you have a hashref rather than a hash.
Oh, Perl... *sighs* I usually use Python :)
for $key (sort keys %{$hashref}) { $value = $hashref->{$key}; do_something_with($value) }.)
The thing is, I don't need to sort by keys, I need to sort by ->{key}->{name} or ->{key}{name}, however that works. The impression I got from a bit of googling is that hashes/hashrefs in perl retain the order they were built in, as opposed to dictionaries in python, which do not have an order. If thst isn't the case, of course, then I am a bit screwed :)
Also, $value in this case would be hash itself, right? So I would do something like
my $newhashref;
for $key (sort keys %{$hashref}) {
$value = $hashref->{$key};
$newhashref->{$key}=$value
}
and get the same structure as before, only with sorted keys?
Sorry, hashs and hashrefs confuse the heck out of me.
no subject
no subject
Then I think you'll need something like
foreach my $key (sort { $tags->{$a}->{name} cmp $tags->{$b}->{name} } keys %{$tags}) { ... }
. (Let me know if you'd like that bit explained to you.)(Oh, and
->{key}->{name}
and->{key}{name}
mean the same thing; you can omit the->
between adjacent brackets with hash keys or array subscripts.)The impression I got from a bit of googling is that hashes/hashrefs in perl retain the order they were built in, as opposed to dictionaries in python, which do not have an order.
No, that's not so -- perhaps you're confusing them with arrays in PHP? They're an unholy combination of hashes/dictionaries and arrays: they allow numbers as keys (like arrays) or strings (like hashes), and retain their order.
Perl hashes iterate in random order, pretty mich like dictionaries in Python. And adding a value to a hash can cause the order of the remaining keys to change, as can switching the Perl version. Basically, you shouldn't rely on the order of keys in a hash.
Also, $value in this case would be hash itself, right?
Well, a hashref, so kind of.
So I would do something like [...] and get the same structure as before, only with sorted keys?
No. If you need order preserved, you'll need either a list or an array. (Note that a list is an ephemeral data structure; there aren't any variables of list type.
sort
returns a list, for example, which you can then assign to an array - or process further, e.g. by iterating over it withforeach
.)no subject
But thanks for the help! :)
no subject
A sorted list, strictly speaking.
But yes. Because you can't sort hashes - you sort the list of keys. (Either by the key themselves, or by something based on the key, depending on what you want to accomplish.)