Страницы

Поиск по вопросам

понедельник, 24 февраля 2020 г.

правильная сортировка массива по значению

#php #массивы #алгоритм #сортировка


есть массив

        [0] => Array
            (
                [title] => ITEM1
                [id] => 1
                [voites] => 0
            )

        [1] => Array
            (
                [title] => ITEM2
                [id] => 2
                [voites] => 0
            )

        [2] => Array
            (
                [title] => ITEM3
                [id] => 3
                [voites] => 4 // высший рейтинг
            )
         [3] => Array
            (
                [title] => ITEM4
                [id] => 4
                [voites] => 0
            )


нужно отсортировать по полю voites... и нужно, чтобы не нарушался порядок..
например, обычная отсортировка выводит сначала элемент с наибольшим значение в voites(что
и логично), но остальные, у которых это поле равно 0, выводит с конца... сортирую через
usort()... не получается написать к нему cmp функцию

public function srtCMP($a, $b){
  return $b["voites"] - $a["voites"];
}


повторюсь: нужно, чтобы не нарушался порядок... элементы у которых высший рейтинг
должны подниматься вверх, а остальные оставить как есть

вот так:

        [0] => Array
            (
                [title] => ITEM3
                [id] => 3
                [voites] => 4 // высший рейтинг
            )
        [1] => Array
            (
                [title] => ITEM1
                [id] => 1
                [voites] => 0
            )

        [2] => Array
            (
                [title] => ITEM2
                [id] => 2
                [voites] => 0
            )
         [3] => Array
            (
                [title] => ITEM4
                [id] => 4
                [voites] => 0
            )

    


Ответы

Ответ 1



По сути, имеется две сортировки: по убыванию voites и (при их равенстве) - по возрастанию ключа элемента. Для применения функции usort() надо временно запомнить этот ключ внутри элемента. Например, так: $common = Array( "0" => Array ( "title" => ITEM1, "id" => 1, "voites" => 0 ), "1" => Array ( "title" => ITEM2, "id" => 2, "voites" => 0 ), "2" => Array ( "title" => ITEM3, "id" => 3, "voites" => 4 // высший рейтинг ), "3" => Array ( "title" => ITEM4, "id" => 4, "voites" => 0 ) ); function cmp($a, $b) { if ($a["voites"] == $b["voites"]) { if (end($a) == end($b)) { return 0; } return (end($a) < end($b)) ? -1 : 1; } return ($a > $b) ? -1 : 1; } function add_key(&$item, $key){ array_push($item,$key); } function delete_key(&$item, $key){ array_pop($item); } array_walk($common, 'add_key'); usort($common, 'cmp'); array_walk($common, 'delete_key'); var_dump($common); Результат: array (size=4) 0 => array (size=3) 'title' => string 'ITEM3' (length=5) 'id' => int 3 'voites' => int 4 1 => array (size=3) 'title' => string 'ITEM1' (length=5) 'id' => int 1 'voites' => int 0 2 => array (size=3) 'title' => string 'ITEM2' (length=5) 'id' => int 2 'voites' => int 0 3 => array (size=3) 'title' => string 'ITEM4' (length=5) 'id' => int 4 'voites' => int 0

Ответ 2



А что если просто отсортировать по ключам voites и id? $arr = [ [ "title" => 'ITEM1', "id" => 1, "voites" => 0 ], [ "title" => 'ITEM2', "id" => 2, "voites" => 0 ], [ "title" => 'ITEM3', "id" => 3, "voites" => 4 // высший рейтинг ], [ "title" => 'ITEM4', "id" => 4, "voites" => 0 ] ]; usort($arr, function($a, $b){ if($a['voites'] === $b['voites']) { return (int) $a['id'] < (int) $b['id'] ? -1 : 1; } return (int) $a['voites'] < (int) $b['voites'] ? 1 : -1; }); var_dump($arr); Результат: array(4) { [0]=> array(3) { ["title"]=> string(5) "ITEM3" ["id"]=> int(3) ["voites"]=> int(4) } [1]=> array(3) { ["title"]=> string(5) "ITEM1" ["id"]=> int(1) ["voites"]=> int(0) } [2]=> array(3) { ["title"]=> string(5) "ITEM2" ["id"]=> int(2) ["voites"]=> int(0) } [3]=> array(3) { ["title"]=> string(5) "ITEM4" ["id"]=> int(4) ["voites"]=> int(0) } }

Комментариев нет:

Отправить комментарий