Problem with sorting an array

In a blog template, I have a tagcloud that I’d like to sort by the number of instances of each tag.
I’ve tried a lot of possibilities and scoured the docs in every direction but don’t seem to find the right approach.

My code in the controller:

  // fetch all tags
  $tags = $articles->pluck('tags', ',', true);
  // order tags by number of occurences in blog
  $tags = $tags->sortBy($articles->filterBy('tags', $tag, ',')->count(), $direction = 'desc');

sortBy doesn’t work here. I’ve tried using php usort() and all other sort functions I could think of to no avail.
The way I think I could solve this would be to add the number of instances of each tag in the tags array but I can’t find how to do it and it’s killing me!!!

I’m sure someone will have faced this before me and can share their insights (which will make me look like the php rookie I am). :slight_smile:

What is the result of this statement?

$articles->filterBy('tags', $tag, ',')->count()

because sortBy() needs to get a string.

Also, I think, you’re using the filerBy() method not correctly. In the code you posted, you’re filtering by comparing the field tags with the value ,, by using the operator $tag!? I don’t understand this.

Your code doesn’t work because of two reasons:

  • $tags is no Kirby collection but a simple array.
  • Even if it was a collection, $tag wouldn’t be defined.

(Also, $direction = 'desc' should be 'desc' without storing the value, but it would work like this anyway.)

usort is actually the right approach:

$tags = $articles->pluck('tags', ',', true);
usort($tags, function($a, $b) use($articles) {
  $aCount = $articles->filterBy('tags', $a, ',')->count();
  $bCount = $articles->filterBy('tags', $b, ',')->count();

  return strcmp($aCount, $bCount);

However please note that this will probably not be performing very well. That depends on the number of tags.

The syntax is actually correct to filter with splitting (see the tags solution in the docs). However you are right that this is missing from the cheat sheet. I will add it, thanks for pointing that out. :slight_smile:

Thanks for your reply!
I do not understand the function($a, $b) as a second parameter for the usort.
Could you explain what this is doing?

That is explained in the PHP docs you linked to above. Basically PHP will pass in two tags and your function needs to compare them and return either -1, 0 or 1 depending on which value is larger. That’s just how sorting works in computer science. :slight_smile:

1 Like

Thanks a lot for helping out on this!
I had to swith $a and $b to get the order in descending but it all worked out!
I turned my head around your solution and the countless examples before using it and I think I got a good unuderstanding of it. Interesting stuff!
Thanks again for your help :slight_smile:

You can also return -strcmp($aCount, $bCount) (note the minus), that will reverse the order as well and might be easier to understand for other people reading your code.

Even better!
Thanks, I’ve edited my code to include your latest comment and added some comments in the code also :wink: