непонятная работа usort

smike

Новичок
PHP:
<?php

$items=[
    ['name'=>'a','require'=>[]],
    ['name'=>'b','require'=>['a']],
    ['name'=>'c','require'=>['b']],
    ['name'=>'d', 'require'=>['c']]

];

shuffle($items);

usort($items, function($a,$b){
    if(in_array($b['name'],$a['require'])){
        return -1;
    }
    if(in_array($a['name'],$b['require'])){
        return 1;
    }
    return 0;
});

print_r($items);

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

smike

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

damner2

Новичок
судя по твоему ответу, ты меня не совсем правильно понял...
это она у тебя не для всех пар корректно выполняется (корректно выполняется = возвращает тот результат, который привёл бы к той последовательности, которую ты ожидаешь)
 

smike

Новичок
Нет, проблема как раз в том, что сравнение выполняетя не для всех пар массива:
PHP:
<?php

$items=[
    ['name'=>'a','require'=>[]],
    ['name'=>'b','require'=>['a']],
    ['name'=>'c','require'=>['b']],
    ['name'=>'d', 'require'=>['c']]

];

shuffle($items);
$compared=0;
usort($items, function($a,$b){
    global $compared;
    $compared++;
    if(in_array($b['name'],$a['require'])){
        return -1;
    }
    if(in_array($a['name'],$b['require'])){
        return 1;
    }
    return 0;
});

print_r($items);
echo $compared;
$compared всегда равно 4.
 

fixxxer

К.О.
Партнер клуба
Выполняется минимально необходимое количество сравнений. А твоя функция сортировки не определяет четкого порядка для любой пары элементов - твое return 0 для usort означает "равны", а не "фиг знает".
Если я правильно понимаю, чего ты хочешь добиться - то делать придется в 2 прохода: сначала построить цепочки зависимостей, а потом уже сортировать.
 
Сверху