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;
});