Многопользовательский ассоциативный массив в PHP

Рассмотрим следующий ассоциативный массив

$arr = Array
(        
    [banana] => 2
    [cherry] => 1
    [orange] => 3
    [grapefruit] => 1
    [apple] => 1
)

Я хочу отсортировать его таким образом, который был бы похож на PLSQL-термины: A DESC, B ASC  (где A - значение, а B - ключ), что означает:

$arr = Array
(
    [orange] => 3
    [banana] => 2
    [apple] => 1
    [cherry] => 1
    [grapefruit] => 1        
)

чтобы апельсин и банан были первыми из-за VALUE, но тогда у меня есть яблоко, вишня и грейпфрут в алфавитном порядке, потому что они имеют одинаковое значение VALUE.

Что я пробовал:
1. для запуска ksort(), а затем asort()/rsort(), надеясь, что второй сорт поднимется оранжевым и бананом до начала массива, не испортив алфавитный вид других 3 предметов. Я был неправ. это все испортит. Итак, я проверил:
2. функции сортировки и array_multisort(). Но, по-видимому, он сортирует сразу несколько массивов или многомерный массив.
3. Я также попытался определить следующую функцию сравнения:

function cmp($a, $b)
{
    foreach ($a as $key1 => $val1) {
        foreach ($b as $key2 => $val2) {
            if($val1 == $val2){
                return strcmp($key1,$key2);
            }
            else if ($val1 > $val2){
                return 1;
            }
            else{ // $val1 < $val2
                return -1;
            }
        }
    }    
} 

и назовите его usort(), но он также не работает.

Итак, мой вопрос: есть ли метод PHP, который реализует запрошенное поведение?

Для Eugen:
Я попробовал, и он не работает перед сортировкой:

Array
(
    [lamb] => 3
    [rule] => 1
    [children] => 1
    [teacher] => 2
    [eager] => 1
)

и после сортировки:

Array
(
    [children] => 1
    [eager] => 1
    [rule] => 1
    [teacher] => 2
    [lamb] => 3
)

Ответ 1

Вы можете использовать array_multisort

<?php
    $arr = Array
    (        
        'banana' => 2,
        'cherry' => 1,
        'orange' => 3,
        'grapefruit' => 1,
        'apple' => 1
    );

    $values = array_values($arr);
    $keys = array_keys($arr);

    //first sort by values desc, then sort by keys asc
    array_multisort($values, SORT_DESC, $keys, SORT_ASC, $arr);

    print_r($arr);
    // output:
    /*
    Array
    (
        [orange] => 3
        [banana] => 2
        [apple] => 1
        [cherry] => 1
        [grapefruit] => 1
    )
    */

?>

Он работает следующим образом:

  • для каждого столбца, который используется для сортировки (значения и ключи для вас), создайте новый массив 1d с его содержимым
  • передайте эти 1d массивы функции array_multisort в вашем порядке сортировки (так что сначала значения $, затем $keys), добавьте порядок сортировки для каждого массива
  • последним аргументом должен быть массив, который вы хотите отсортировать.

(Возможно, вы найдете это объяснение легче понять)

Ответ 2

function polysortcmp($a, $b) {
  if ($a[1]<$b[1]) return 1;
  if ($a[1]>$b[1]) return -1;
  if ($a[0]<$b[0]) return -1;
  if ($a[0]>$b[0]) return 1;
  return 0;
}


function polysort(&$arr) {
  foreach ($arr as $k=>$v) $arr[$k]=array($k,$v);
  uasort($arr, "polysortcmp");
  foreach ($arr as $k=>$v) $arr[$k]=$v[1];
}

Ответ 3

используется функция сортировки массива arsort.

$arr = array(        
        'banana' => 2,
        'cherry' => 1,
        'orange' => 3,
        'grapefruit' => 1,
        'apple' => 1
    );

arsort($arr);
print_r($arr);

Выход

Array ( [orange] => 3 [banana] => 2 [apple] => 1 [grapefruit] => 1 [cherry] => 1 )