Reputation: 4887
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)
Upvotes: 2
Views: 92
Reputation: 12389
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.
Upvotes: 2
Reputation: 6922
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).
Upvotes: 1