2013-04-10 12 views
5

Szukam, jak zbudować ranker tablicy na podstawie wartości.ranker tablic php na podstawie wartości

mam wyjście array jak:

key => 0 | id => 16103 | Thumbs => 0 
key => 1 | id => 23019 | Thumbs => 0 
key => 2 | id => 49797 | Thumbs => 5 <- key 2 needs to switch with key 1 
key => 3 | id => 51297 | Thumbs => 0 
key => 4 | id => 58106 | Thumbs => 0 
key => 5 | id => 59927 | Thumbs => 4 <- will be stay at this position 
key => 6 | id => 61182 | Thumbs => 0 
key => 7 | id => 68592 | Thumbs => 0 
key => 8 | id => 70238 | Thumbs => 10 <- key 8 needs to switch with key 6 
key => 9 | id => 71815 | Thumbs => 0 
key => 10 | id => 78588 | Thumbs => 0 
etc.. 

Chciałbym napisać funkcję do odtworzenia tablicy wyjście powyżej następująco. Kiedy rekord ma 5 kciuków, musi przenieść "jeden" wyżej na wyjściu, gdy ma 10 kciuków 2 wyżej i tak dalej.

Chyba powinienem najpierw odtworzyć tablicę, aby ustawić klucz (prio) dla każdego wyjścia, na przykład 100,200,300, więc mamy wystarczająco dużo miejsca, żeby ustawić wiersz pomiędzy?

Z góry dziękuję!

+0

Czy chcesz, aby klawisz 8 znajdował się u góry, klawisz 2 na drugiej pozycji, a następnie co drugi wpis o wartości 4 lub mniejszej? lub czy klucz 2 po prostu idzie w górę do klawisza 1, a klawisz 8 do klawisza 6? – Chris

+0

Sądzę, że powinieneś zrobić jakiś licznik (jeszcze jedno pole), w którym przechowujesz tymczasowe "kciuki" i jeśli osiągnie pięć, sortujesz tablicę, a następnie ustawiasz ją na zero, aby nie dwa razy podnosić. – Voitcus

+0

@Chris te wyniki pochodzą z akcji wyszukiwania, więc mają już pewną wagę. Nie odrzucę wszystkiego, by powiedzieć, że wynik większości kciuków jest najlepszy. Chcę stworzyć rodzaj kombinacji między algorytmem wyszukiwania a user_inputs, dlatego chciałbym rangować "delikatnie" przez (przez dane wejściowe użytkownika) podane kciuki. 5 kciuków oznacza jedną pozycję wyżej, 10 kciuków 2 pozycje wyżej itd. – directory

Odpowiedz

1

Myślę, że w twoim przykładzie lepiej użyć tablicy tablic. (Jeśli jeszcze nie jesteś, nie wynika to z pytania.) Tak jak w przypadku.

$array = array(); 
$array[0] = array('id'=>16103, 'Thumbs'=>0); 
$array[1] = array('id'=>16103, 'Thumbs'=>0); 
... 

Następnie zacznij od napisania funkcji wymiany.

function swap (&$arr,$key1,$key2) { 
    $temp=$arr[$key1]; 
    $arr[$key1]=$arr[$key2]; 
    $arr[$key2]=$temp; 
    // the & before the $arr parameter makes sure the array is passed as a reference. So no need to return the new array at the end. 
} 

teraz do funkcji Ranking:

function rank(&$arr) { 
    for ($i = 0; $i < count($arr); $i++) { 
     if ($arr[$i] < 5) continue; 
     $places_to_move = $arr[i]['Thumbs']/5; // get number of places to promote the entry 
     $places_to_move = max($places_to_move, $i); // make sure we don't move it out of the array bounds 
     swap($arr, $i, $i - $places_to_move); 
    } 
} 

Następnie wystarczy zadzwonić do funkcji postój na swojej tablicy unranked

rank($array); 
+0

Dlaczego w dół? Myślę, że to lepsze podejście niż moja odpowiedź. – enrey

+0

To nie daje mi wyników w rankingu, a otrzymanie tablicy za pomocą funkcji dostarcza tej samej tablicy:/Twoja funkcja wydaje się rangować wyniki w porządku ?! – directory

0

Tak więc, jeśli dobrze rozumiem, masz tablicę tablic :

$array = array(
    array('key' => 0, 'id' => 16103, 'Thumbs' => 0), 
    array('key' => 1, 'id' => 23019, 'Thumbs' => 0), 
    array('key' => 2, 'id' => 49797, 'Thumbs' => 5), //<- key 2 needs to switch with key 1 
    array('key' => 3, 'id' => 51297, 'Thumbs' => 0), 
    array('key' => 4, 'id' => 58106, 'Thumbs' => 0), 
    array('key' => 5, 'id' => 59927, 'Thumbs' => 4), //<- will be stay at this position 
    array('key' => 6, 'id' => 61182, 'Thumbs' => 0), 
    array('key' => 7, 'id' => 68592, 'Thumbs' => 0), 
    array('key' => 8, 'id' => 70238, 'Thumbs' => 10), //<- key 8 needs to switch with key 6 
    array('key' => 9, 'id' => 71815, 'Thumbs' => 0), 
    array('key' => 10, 'id' => 78588, 'Thumbs' => 0) 
); 

W tym przypadku można użyć usort():

usort($array, function($a, $b){ 
    $a_thumbs_val = floor($a['Thumbs']/5); 
    $a_val = $a_thumbs_val ? $a['key'] - $a_thumbs_val - 0.5 : $a['key']; 

    $b_thumbs_val = floor($b['Thumbs']/5); 
    $b_val = $b_thumbs_val ? $b['key'] - $b_thumbs_val - 0.5 : $b['key']; 
    return ($a_val > $b_val) ? 1 : -1; 
}); 


var_dump($array); 

przyniosłoby:

array (size=11) 
    0 => 
    array (size=3) 
     'key' => int 0 
     'id' => int 16103 
     'Thumbs' => int 0 
    1 => 
    array (size=3) 
     'key' => int 2 
     'id' => int 49797 
     'Thumbs' => int 5 
    2 => 
    array (size=3) 
     'key' => int 1 
     'id' => int 23019 
     'Thumbs' => int 0 
    3 => 
    array (size=3) 
     'key' => int 3 
     'id' => int 51297 
     'Thumbs' => int 0 
    4 => 
    array (size=3) 
     'key' => int 4 
     'id' => int 58106 
     'Thumbs' => int 0 
    5 => 
    array (size=3) 
     'key' => int 5 
     'id' => int 59927 
     'Thumbs' => int 4 
    6 => 
    array (size=3) 
     'key' => int 8 
     'id' => int 70238 
     'Thumbs' => int 10 
    7 => 
    array (size=3) 
     'key' => int 6 
     'id' => int 61182 
     'Thumbs' => int 0 
    8 => 
    array (size=3) 
     'key' => int 7 
     'id' => int 68592 
     'Thumbs' => int 0 
    9 => 
    array (size=3) 
     'key' => int 9 
     'id' => int 71815 
     'Thumbs' => int 0 
    10 => 
    array (size=3) 
     'key' => int 10 
     'id' => int 78588 
     'Thumbs' => int 0 

Uwaga: 2 wpisy, które powinny być na tej samej pozycji mogą być sposobem arround, ponieważ usort robi niestabilny sortowania. Możesz to osiągnąć, wzmacniając to zamknięcie w usort, dodając bardziej skomplikowane porównanie.

Powiązane problemy