Search code examples
phpranking

How to define an equation to calculate rank of object (restaurant) based on weights


I have an array of restaurants and I need to calculate a rank for every restaurant based on these rules:

  • distance from me in kilometers (weight=30)
  • likes (weight=10)
$restaurants = [
 {name: "KFC", distance: 17, likes: 3},
 {name: "Macdonalds", distance: 2, likes: 9},
 {name: "Pizza Hut", distance: 9, likes: 12},
 {name: "Burger King", distance: 14, likes: 17},
];

The higher rank means that this restaurant is close to me and have more likes based on an equation.

What should be the equation?


Solution

  • Here's one possible solution to your problem. We use a weights array with keys matching those in the restaurants array and values as shown in your question. Note that for distance we use a negative value since you want closer restaurants (lower distance values) to be more highly ranked. We can then sort the restaurants array by the sum of the ratings based on each weight:

    function get_rating($restaurant, $weights) {
        $rating = 0;
        foreach ($weights as $factor => $weight) {
            $rating += $weight * $restaurant[$factor];
        }
        return $rating;
    }
    
    $weights = array('distance' => -30, 'likes' => 10);
    
    usort($restaurants, function ($a, $b) use ($weights) {
        return get_rating($b, $weights) - get_rating($a, $weights);
    });
    
    print_r($restaurants);
    

    Output:

    Array
    (
        [0] => Array
            (
                [name] => Macdonalds
                [distance] => 2
                [likes] => 9
            )
        [1] => Array
            (
                [name] => Pizza Hut
                [distance] => 9
                [likes] => 12
            )
        [2] => Array
            (
                [name] => Burger King
                [distance] => 14
                [likes] => 17
            )
        [3] => Array
            (
                [name] => KFC
                [distance] => 17
                [likes] => 3
            )
    )
    

    Demo on 3v4l.org

    Note the $restaurants variable in your question is not a valid PHP structure; I've assumed you have an associative array.