So I am pretty lost here because I don’t know what my object looks like (not sure why I can’t do print_r()
to print the object).
Basically from the below code, I need to sort the reviews which is $_reviews
based on $percent_avg
. I got the $percent_avg
value from a multiple for loops and that’s what complicates things. I am not sure how can I make a new sorted array based on that $percent_avg
variable.
$_reviews = $block->getReviewCollection($_item->getID()); $sorted_reviews = []; $sorted_percentage = []; foreach ($_reviews as $_review) { $total_percent = 0; foreach ($_review->getRatingVotes() as $_vote){ $total_percent += $_vote->getPercent(); } $percent_avg = $total_percent/3; array_push($sorted_percentage, $percent_avg); }
I have attempted the above code to sort the reviews, what I think is that I can make a new array for a sorted $percent_avg
and compare that value with the $_reviews
object? But with this, it will be pretty slow?
//sort array sort($sorted_percentage); //run a for loop - if the value in $sorted_percentage matches $percent_avg, push it to a new array foreach ($sorted_percentage as $percent) { foreach ($_reviews as $_review) { $total_percent = 0; foreach ($_review->getRatingVotes() as $_vote){ $total_percent += $_vote->getPercent(); } $percent_avg = $total_percent/3; if($percent_avg == $percent){ array_push($sorted_reviews, $_review); } } }
The above is just an idea and it is not working.
I am still new to PHP, so any suggestions/helps will be appreciated. Thank you.
Advertisement
Answer
If you want to sort $_reviews
based on the sum of each review’s getRatingsVotes()
‘ getPercent()
, you can use usort()
:
usort( $_reviews, function( $a, $b ) { $a_total = 0; foreach ( $a->getRatingVotes() as $_vote ) { $a_total += $_vote->getPercent(); } $b_total = 0; foreach ( $b->getRatingVotes() as $_vote ) { $b_total += $_vote->getPercent(); } return $a_total <=> $b_total; });
This may be slow if $_reviews
contains many elements, or if individual reviews tend to contain many votes. You can speed it up by caching $a_total
and $b_total
, and using those cached numbers where possible:
usort( $_reviews, function( $a, $b ) { if ( array_key_exists( 'total', $a ) ) { // Fetch from cache: $a_total = $a['total']; } else { // Calculate and store in cache: $a_total = 0; foreach ( $a->getRatingVotes() as $_vote ) { $a_total += $_vote->getPercent(); } $a['total'] = $a_total; } if ( array_key_exists( 'b_total', $b ) ) { // Fetch from cache: $b_total = $b['total']; } else { // Calculate and store in cache: $b_total = 0; foreach ( $b->getRatingVotes() as $_vote ) { $b_total += $_vote->getPercent(); } $b['total'] = $b_total; } return $a_total <=> $b_total; });