Вопрос

I have an array of rating numbers.

array(34, 35, 33, 17, 38, 29, 31, 23)

I want the numbers to automatically turn into a rating between 1 and 5 (1, 2, 3, 4 or 5).

Example

  • "38" (highest number) should have a rating of 5
  • "17" (lowest number) should have a rating of 1.
  • "31" should probably have a rating of 3.

How do I calculate this with PHP code? The highest number might be higher than 35 and the lowest might be lower than 17.

Это было полезно?

Решение

You are trying to map the numbers 17 and 38 to the numbers 1 and 5, interpolating all values in between. Let us use these numbers in the below example where num represents any number from the range:

(num - 17)                  maps 17 and 38 to 0 and 21
(num - 17) / (21)           maps  0 and 21 to 0 and  1
(num - 17) / (21) * (4)     maps  0 and  1 to 0 and  4
(num - 17) / (21) * (4) + 1 maps  0 and  4 to 1 and  5

PHP Code:

function mapvaluetorange($array, $a, $b) {
    $map = array();
    $min = min($array);
    $max = max($array);
    foreach ($array as $value) {
        $map[] = array(
            "old" => $value,
            "new" => ($value - $min) / ($max - $min) * ($b - $a) + $a
        );
    }
    return $map;
}
$map = mapvaluetorange(array(34, 35, 33, 17, 38, 29, 31, 23), 1, 5);

Output:

int(34) -> float(4.2380952380952)
int(35) -> float(4.4285714285714)
int(33) -> float(4.047619047619)
int(17) -> int(1)
int(38) -> int(5)
int(29) -> float(3.2857142857143)
int(31) -> float(3.6666666666667)
int(23) -> float(2.1428571428571)

Use the round function to round floats to integers.

Другие советы

As an alternate approach, you could use an anonymous function and array_map() to map the values of the array to the range you want like this:

    <?php
    $x = array(34, 35, 33, 17, 38, 29, 31, 23);
    $max = max($x);
    $min = min($x);
    $map = function($value) use($min,$max) {return (int)round((($value-$min)/($max-$min))*4+1);};
    $x = array_map($map, $x);
    var_dump($x);

Gives:

    array(8) {
        [0] =>   int(4)
        [1] =>   int(4)
        [2] =>   int(4)
        [3] =>   int(1)
        [4] =>   int(5)
        [5] =>   int(3)
        [6] =>   int(4)
        [7] =>   int(2)
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top