Как присвоить номер ранга массиву, когда существуют связи

Я изо всех сил пытаюсь понять, с чего начать, пытаясь присвоить ранги числовым значениям в массиве, когда есть связи. Так, например, мне нужно повернуть массив следующим образом:

myarray = (4,76,34,13,34) 

в другой массив, например:

 myarray2 = (1,5,3.5,2,3.5) 

В принципе, когда одно и то же число встречается более одного раза в массиве, присвоенный ранг этим числам является средним числом рангов. Таким образом, вместо двух 34-х, занявших 3-е и 4-е места, оба получают задание 3.5. Точно так же, если бы было 3 копии 34, то 3 назначенных ранга были бы разделены на 3. Любая помощь была бы высоко оценена!

Большое спасибо,

Адам

Мне было весело с этим!

 function rank($input) { $output = array(); $ranking = $input; sort($ranking); $ranking = array_flip($ranking); $last_val = -1; foreach($ranking as $key => $val){ $repetitions = ($val-$last_val-1); $last_val = $val; if($repetitions) { $ranking[$key] = (($val*($repetitions+1))-($repetitions+1)*(($repetitions)/2))/($repetitions+1)+1 ; } else { $ranking[$key] = $val+1; } } foreach($input as $key => $val){ $output[$key] = $ranking[$val]; } return $output; } 

Используйте его так:

 $a = array(4,76,34,13,34); $c = rank($a); print_r($c); 

выведет:

 Array ( [0] => 1 [1] => 5 [2] => 3.5 [3] => 2 [4] => 3.5 ) 

это то же самое, что:

 Array(1, 5, 3.5, 2, 3.5) 

как и ожидалось!

Вот один из способов сделать это.

 <?php $myarray = array(4,76,34,13,34); $sorted_array = $myarray; $grouped_array = array(); sort($sorted_array); foreach ($sorted_array as $rank => $entry) { // Initialize the entry if it doesn't already exist if (empty($grouped_array[$entry])) { $grouped_array[$entry]['count'] = 1.0; $grouped_array[$entry]['total'] = $rank + 1; // Account for 0-based array } else { $grouped_array[$entry]['count'] += 1.0; $grouped_array[$entry]['total'] += $rank + 1; // Account for 0-based array } } $myarray2 = array(); foreach ($myarray as $entry) { // Get the average $myarray2[] = $grouped_array[$entry]['total'] / $grouped_array[$entry]['count']; } 

Я предполагаю, что вам также необходимо обрабатывать случаи, когда есть три или четыре или n значения, связанные с одним и тем же рангом.

Я не PHP-гуру, но вот подход (псевдо-код) к определению функции ранга:

 define a = original array define s = a.Sorted define rank(n) = (s.FirstIndexOf(n) + s.LastIndexOf(n)) / 2 

Вам может потребоваться несколько примеров на бумаге, чтобы убедить себя, что это работает даже для троек и выше; он зависит от сортировки s , чтобы дубликаты были смежными.

Принятое решение (и другие тоже) кажется более сложным, чем нужно:

 function Rank($data) { $count = 0; $unique = $data; sort($unique); $unique = array_count_values($unique); foreach ($unique as $key => $frequency) { foreach (range(1, $frequency) as $i) { $unique[$key] += $count++; } $unique[$key] /= $frequency; } foreach ($data as $key => $value) { $data[$key] = $unique[$value]; } return $data; } 

Пример ( демонстрация ):

 print_r(Rank(array(4, 76, 34, 13, 34))); // 1; 5; 3.5; 2; 3.5 print_r(Rank(array(4, 76, 34, 13, 34, 34))); // 1; 6; 4; 2; 4; 4