2015-02-08 2 views
2

Сложно объяснить, так вот пример:Как отсортировать массив ассоциативных массивов по значению ключа в PHP

$strings = array(
    array("languageCode" => "ES", "string" => "hola"), 
    array("languageCode" => "EN", "string" => "hello"), 
    array("languageCode" => "IT", "string" => "ciao"), 
    array("languageCode" => "CHS", "string" => "您好"), 
); 

Я хотел бы отсортировать строки по languageCode значение, определяя порядок:

function magicStringOrder(array $strings, array $languageCodeOrder){ 
    // .... 
    return $strings; 
} 

$strings = magicStringOrder($strings, array('EN', 'IT')); 

$strings = array(
    array("languageCode" => "EN", "string" => "hello"), 
    array("languageCode" => "IT", "string" => "ciao"), 
    array("languageCode" => "ES", "string" => "hola"), 
    array("languageCode" => "CHS", "string" => "您好"), 
); 

magicStringOrder?

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

+0

Каково ваше ожидание значений, у которых нет записи в вашем языке? –

+0

@MarkBaker, если определенный порядок принимает позицию, в противном случае сохраняет свою позицию –

ответ

2

Другая идея без функций PHP сортировки:

// sort by cmp $arr[$magic_key] <-> arr $magic_order 
function magicSort($arr, $magic_key="", $magic_order = array()) 
{ 
    $sorted = array(); 
    foreach($magic_order AS $v) { 
    foreach($arr AS $k2 => $v2) { 
     if($v===$v2[$magic_key]) { 
     $sorted[] = $v2; 
     unset($arr[$k2]); 
     } 
    } 
    } 

    // attach what's left 
    return array_merge($sorted, $arr); 
} 

Test it at eval.in (ссылка истекает в ближайшее время)

$strings = array(
    array("languageCode" => "ES", "string" => "hola"), 
    array("languageCode" => "EN", "string" => "hello"), 
    array("languageCode" => "IT", "string" => "ciao"), 
    array("languageCode" => "CHS", "string" => "??"), 
); 

print_r(magicSort($strings, "languageCode", array("EN", "IT"))); 

выходы:

Array 
(
    [0] => Array 
     (
      [languageCode] => EN 
      [string] => hello 
     ) 

    [1] => Array 
     (
      [languageCode] => IT 
      [string] => ciao 
     ) 

    [2] => Array 
     (
      [languageCode] => ES 
      [string] => hola 
     ) 

    [3] => Array 
     (
      [languageCode] => CHS 
      [string] => 您好 
     ) 

) 

$magic_order также может быть пустым. Если это так, массив просто переиндексируется. Массивы со значениями, которые не существуют в $magic_order, сдвигаются вниз, и порядок их сохраняется.

Не уверен, что это именно то, что вам нужно.

+1

- хорошая идея! –

+0

после теста это быстрее –

+0

Это работает довольно просто, рад, что вам это нравится @SimoneNigro :) –

1

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

Вы можете использовать asort, чтобы отсортировать массив на основе $languageCodeOrder сохраненных весов. Если языка нет в $languageCodeOrder, его вес становится 0 и идет к концу упорядоченного массива.

Окончательный порядок массива будет от высокого до низкого. То есть: если EN имеет вес 1, он появится в массиве после ИТ, который имеет 2.

$strings = array(
    array("languageCode" => "ES", "string" => "hola"), 
    array("languageCode" => "EN", "string" => "hello"), 
    array("languageCode" => "IT", "string" => "ciao"), 
    array("languageCode" => "CHS", "string" => "您好"), 
); 

function magicStringOrder(array $strings, array $languageCodeOrder) { 
    uasort($strings, function($a,$b) use ($languageCodeOrder) { 
     $val_a = (isset($languageCodeOrder[$a["languageCode"]])) ? $languageCodeOrder[$a["languageCode"]] : 0; 
     $val_b = (isset($languageCodeOrder[$b["languageCode"]])) ? $languageCodeOrder[$b["languageCode"]] : 0; 

     return $val_b - $val_a; 
    }); 
    return $strings; 
} 

$strings_ordered = magicStringOrder($strings, array('EN' => 1, 'IT' => 2, 'ES' => 3, 'CHS' => 4)); 

print_r($strings_ordered); 

Если массивы большие, это лучше полагаться на алгоритмах сортировки PHP, а не пытаться реализовать пользовательские те ,

Не стесняйтесь модифицировать что-либо в алгоритме (заказ или что-то еще).

+0

, функция почти такая, как я бы (см. Мое редактирование). Тем не менее, я бы предпочел, чтобы языки не присутствовали в заказе, сохраняли свою позицию. Если возможно, было бы лучше, если бы индекс был пересчитан на основе новых позиций (0,1,2) и (1,2,4). Большое спасибо –

+0

Извините, удаляет мое редактирование, неправильно –

+0

@SimoneNigro не беспокоится, рад, что это помогло, удачи :) – acontell

Смежные вопросы