Skip to content

Instantly share code, notes, and snippets.

@vertexvaar
Last active April 17, 2020 15:24
Show Gist options
  • Select an option

  • Save vertexvaar/08eb76d55b72ce39af1593429970308b to your computer and use it in GitHub Desktop.

Select an option

Save vertexvaar/08eb76d55b72ce39af1593429970308b to your computer and use it in GitHub Desktop.
Sort an multi dimensional array by unique array value in custom order
<?php
$functions = [
'usort (from stackoverflow)' => function (array $input, array $order): array {
usort(
$input,
function ($a, $b) use ($order) {
$pos_a = array_search($a['id'], $order);
$pos_b = array_search($b['id'], $order);
return $pos_a - $pos_b;
}
);
return $input;
},
'using a pre-indexed array (sorin)' => function (array $input, array $order) {
$sortedRecords = [];
foreach ($order as $uid) {
$sortedRecords[$uid] = null;
}
foreach ($input as $record) {
$sortedRecords[$record['id']] = $record;
}
return $sortedRecords;
},
'using a pre-indexed array with flip (sorin + olli)' => function (array $input, array $order) {
$sortedRecords = array_flip($order);
foreach ($input as $record) {
$sortedRecords[$record['id']] = $record;
}
return $sortedRecords;
},
'array_replace' => function (array $input, array $order) {
$flippedOrder = array_flip($order);
$indexedInput = array_column($input, null, 'id');
return array_replace($flippedOrder, $indexedInput);
},
'array_map (olli)' => function (array $input, array $order) {
$indexedRecords = array_column($input, null, 'id');
$getRecordByUid = function (int $uid) use ($indexedRecords): array {
return $indexedRecords[$uid] ?? [];
};
return array_map($getRecordByUid, $order);
},
'array_column + foreach (olli)' => function (array $input, array $order) {
$indexedRecords = array_column($input, null, 'id');
$sortedRecords = [];
foreach ($order as $uid) {
$sortedRecords[] = $indexedRecords[$uid];
}
return $sortedRecords;
},
'array_walk (olli + sorin)' => function (array $input, array $order) {
$recordIndex = array_column($input, 'id');
$getRecord = function (int $uid) use ($recordIndex, $input) {
$index = array_search($uid, $recordIndex);
return $input[$index];
};
array_walk($order, $getRecord);
return $order;
},
'1 foreach with ksort' => function (array $input, array $order) {
$index = array_flip($order);
$sortedRecords = [];
foreach ($input as $record) {
$sortedRecords[$index[$record['id']]] = $record;
}
ksort($sortedRecords);
return $sortedRecords;
},
];
function runFunctions(array $functions, int $iterations, int $elements): array
{
$order = [];
$array = [];
for ($i = 0; $i < $elements; $i++) {
$id = rand(0, PHP_INT_MAX);
$order[] = $id;
$array[] = ['id' => $id, 'title' => uniqid()];
}
foreach ($functions as $funcName => $function) {
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) {
$result = $function($array, $order);
}
$end = microtime(true);
$times[$funcName] = ($end - $start);
}
asort($times);
echo $iterations . ' iterations With ' . $elements . ' elements' . PHP_EOL;
print_r($times);
return $times;
}
for ($i = 1; $i <= 1000000; $i *= 10) {
runFunctions($functions, 1000, $i);
}
@vertexvaar

Copy link
Copy Markdown
Author
With 8 elements
Array
(
    [array_replace] => 0.56302499771118
    [using a pre-indexed array with flip (sorin + olli)] => 0.61353898048401
    [array_column + foreach (olli)] => 0.65558290481567
    [using a pre-indexed array (sorin)] => 0.76836705207825
    [1 foreach with ksort] => 0.81171798706055
    [array_map (olli)] => 1.7615189552307
    [array_walk (olli + sorin)] => 2.5643401145935
    [usort (from stackoverflow)] => 3.6155331134796
)
With 4 elements
Array
(
    [using a pre-indexed array with flip (sorin + olli)] => 0.47339820861816
    [array_column + foreach (olli)] => 0.51283097267151
    [using a pre-indexed array (sorin)] => 0.52264809608459
    [array_replace] => 0.52775907516479
    [1 foreach with ksort] => 0.63797903060913
    [array_map (olli)] => 1.142077922821
    [array_walk (olli + sorin)] => 1.5454430580139
    [usort (from stackoverflow)] => 2.5230751037598
)
With 100 elements
Array
(
    [array_replace] => 1.3828339576721
    [using a pre-indexed array with flip (sorin + olli)] => 3.6822819709778
    [array_column + foreach (olli)] => 3.8780760765076
    [1 foreach with ksort] => 4.8685579299927
    [using a pre-indexed array (sorin)] => 6.1783819198608
    [array_map (olli)] => 16.787395000458
    [array_walk (olli + sorin)] => 27.845643043518
    [usort (from stackoverflow)] => 140.46105909348
)

Process finished with exit code 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment