如何按PHP中的键值对关联数组进行排序

Tough to explain so here's an example:

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

I would like to sort strings by languageCode value, by defining the order:

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" => "您好"),
);

There is magicStringOrder?

I now know that it is a simple problem to solve with a few loops. I would need a very fast function (it is called many times, with large array)

Another idea without php sort functions:

// 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 (link expires soon)

$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")));

outputs to:

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 can also be empty. If so, the array is just reindexed. Arrays with values, that don't exist in $magic_order are shifted down and order of those is maintained.

Not sure, if that's exactly what you need.

If it's not a problem to give a weight to a language, the sorting becomes much easier and therefore quicker.

You can use asort to sort the array based on the $languageCodeOrder stored weights. If a language it's not present in the $languageCodeOrder its weight becomes 0 and goes towards the end of the ordered array.

The final order of the array will be from high weight to low. That is: if EN has a weight of 1 it will appear in the array after IT that has 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);

If the arrays are big, it's better to rely on PHP sort algorithms rather than trying to implement custom ones.

Feel free to modify anything in the algorithm (order or whatever).