带有额外标志的多维数组排序

I'm trying to sort a multidimensional array with an extra flag. The array got childs with name and a optional checked flag. I want to sort this array by checked, and then name. I've got this working fine on the name part, but I can't seem to get the checked flag in it.

<?php

$data = array(
    array(
        'name' => 'C'
    ),
    array(
        'name' => 'A'
    ),
    array(
        'name' => 'E',
        'checked' => true
    ),
    array(
        'name' => 'B',
        'checked' => true
    ),
    array(
        'name' => 'F'
    ),
    array(
        'name' => 'D'
    )
);

usort($data, function($a, $b) {
    return strcmp($a['name'], $b['name']);
});

For the record: I want this as the result: B E A C D F

Any help would be appreciated.

Within usort you can "prioritize" the checked flag:

usort($data, function($a, $b) {

    $diff = strcmp($a['name'], $b['name']);

    if (isset($a['checked']) && isset($b['checked'])) return $diff;
    if (isset($a['checked'])) return -1;
    if (isset($b['checked'])) return 1;
    return $diff;
});

If you ever add in 'checked' => false attributes, you'd have to change the logic accordingly.

Split the array into two parts (checked and not), sort separately, and merge the result:

function filterAndSort($array, $checked = true) {
    $array = array_filter($array, function ($a) use ($checked) {
        return $checked ? isset($a['checked']) : !isset($a['checked']);
    });
    usort($array, function($a, $b) {
        return strcmp($a['name'], $b['name']);
    });
    return $array;
}

$data = array_merge(filterAndSort($data, true), filterAndSort($data, false));

print_r($data);

Outputs:

Array(
    [0] => Array(
        [name] => B
        [checked] => 1
    )
    [1] => Array(
        [name] => E
        [checked] => 1
    )
    [2] => Array(
        [name] => A
    )
    [3] => Array(
        [name] => C
    )
    [4] => Array(
        [name] => D
    )
    [5] => Array(
        [name] => F
    )
)