"004", "n"=>"03"), array("a"=>"003", "n"=>"02"), array("a"=>"001", "n"=>"02")," />

Как отсортировать многомерный массив по ключам умножения?

php sorting multidimensional-array

695 просмотра

3 ответа

823 Репутация автора

Я пытаюсь сделать то же самое, что и запрос MySQL "SELECT * FROM таблицы ORDER BY field1, field2, ..." с многомерным массивом:

$Test = array(
    array("a"=>"004", "n"=>"03"),
    array("a"=>"003", "n"=>"02"),
    array("a"=>"001", "n"=>"02"),
    array("a"=>"005", "n"=>"01"),
    array("a"=>"001", "n"=>"01"),
    array("a"=>"004", "n"=>"02"),
    array("a"=>"003", "n"=>"01"),
    array("a"=>"004", "n"=>"01")
);
function msort(&$array, $keys){
    array_reverse($keys);
    foreach($keys as $key){
        uasort($array, sortByKey);
    }
    //
    function sortByKey($A, $B){

        global $key;

        $a = $A[$key];
        $b = $B[$key];
        if($a==$b) return 0;
        return ($a < $b)? -1 : 1 ;
    }
}
//
msort($Test, array("a","n"));
//
foreach($Test as $t){
    echo('<p>'.$t["a"].'-'.$t["n"].'</p>');
}

Моя теория такова: если я сортирую кратное число раз от менее важного ключа к самому важному ключу, я закажу такой запрос mySQL.

Но php возвращает «Предупреждение: uasort () ожидает, что параметр 2 является допустимым обратным вызовом, функция« sortByKey »не найдена или недопустимое имя функции в /Library/WebServer/Documents/www/teste.array_sort.php в строке 23» (uasort линия)

Это простая функция заказа, что мне не хватает?

Автор: Gustavo Источник Размещён: 02.04.2014 01:13

Ответы (3)


4 плюса

269774 Репутация автора

Вот код, который я написал, чтобы сделать нечто подобное:

uasort($array,function($a,$b) {
    return strcmp($a['launch'],$b['launch'])
        ?: strcmp($a['tld'],$b['tld'])
        ?: strcmp($a['sld'],$b['sld']);
});

Это как бы злоупотребляет тем фактом, что отрицательные числа являются правдивыми (только ноль - ложными), чтобы сначала сравнить launch, а затем tld, потом sld. Вы должны быть в состоянии приспособить это к вашим потребностям достаточно легко.

Автор: Niet the Dark Absol Размещён: 02.04.2014 01:16

0 плюса

823 Репутация автора

Это сделает работу, спасибо за вклад!

function mdsort(&$array, $keys){

    global $KeyOrder;

    $KeyOrder = $keys;
    uasort($array, cmp);    
}
function cmp(array $a, array $b) {

    global $KeyOrder;

    foreach($KeyOrder as $key){
        $res = strcmp($a[$key], $b[$key]);
        if($res!=0) break;
    }
    return $res;
}
//
mdsort($Test, array("a","n"));

Этот код немного уродлив, хотя, я считаю, что он может быть лучше - может быть, класс, чтобы решить проблему передачи массива с ключами в функцию "cmp". Но это отправная точка, вы можете использовать ее с любым количеством ключей для сортировки.

Автор: Gustavo Размещён: 02.04.2014 10:36

6 плюса

418425 Репутация автора

Решение

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

/**
 * Returns a comparison function to sort by $cmp
 * over multiple keys. First argument is the comparison
 * function, all following arguments are the keys to
 * sort by.
 */
function createMultiKeyCmpFunc($cmp, $key /* , keys... */) {
    $keys = func_get_args();
    array_shift($keys);

    return function (array $a, array $b) use ($cmp, $keys) {
        return array_reduce($keys, function ($result, $key) use ($cmp, $a, $b) {
            return $result ?: call_user_func($cmp, $a[$key], $b[$key]);
        });
    };
}

usort($array, createMultiKeyCmpFunc('strcmp', 'foo', 'bar', 'baz'));
// or
usort($array, createMultiKeyCmpFunc(function ($a, $b) { return $a - $b; }, 'foo', 'bar', 'baz'));

Это примерно эквивалентно SQL ORDER BY foo, bar, baz.

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

Автор: deceze Размещён: 03.04.2014 06:16
Вопросы из категории :
32x32