Skip to content
Advertisement

How to sort an array based on another value?

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;
});
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement