Last active
November 12, 2018 11:11
-
-
Save cusster/7150682755d81eb51adff7668aee614f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Get value at a given path expressed in dot notation. | |
* | |
* @param array $arr | |
* @param string $path | |
* @return mixed | |
*/ | |
function array_dot_notation(array $arr, string $path) | |
{ | |
$path = array_map(function($i) { | |
return trim($i); | |
}, explode('.', $path)); | |
foreach ($path as $p) { | |
if (! isset($arr[$p])) { | |
return null; | |
} else { | |
$arr = $arr[$p]; | |
} | |
} | |
return $arr; | |
} | |
/** | |
* Sort multi-dimensional array using multiple predicates. | |
* | |
* @param array $data | |
* @param array $predicates | |
* @return array | |
*/ | |
function msort(array $data, array $predicates): array | |
{ | |
$predicatesArr = []; | |
foreach ($predicates as $predicate => $order) { | |
$predicatesArr[$predicate] = []; | |
foreach ($data as $i => $row) { | |
if (strstr($predicate, '.') !== false) { | |
$valueAtPath = array_dot_notation($row, $predicate); | |
} else { | |
$valueAtPath = $row[$predicate] ?: null; | |
} | |
$predicatesArr[$predicate]['_' . $i] = strtolower($valueAtPath); | |
} | |
if (! count($predicatesArr[$predicate])) { | |
unset($predicatesArr[$predicate]); | |
unset($predicates[$predicate]); | |
} | |
} | |
if (empty($predicatesArr)) { | |
return $data; | |
} | |
$eval = 'array_multisort('; | |
foreach ($predicates as $predicate => $order) { | |
$eval .= '$predicatesArr[\'' . $predicate . '\'],' . $order . ','; | |
} | |
$eval = substr($eval, 0, -1) . ');'; | |
eval($eval); | |
$output = []; | |
foreach ($predicatesArr as $predicate => $predicateArr) { | |
foreach ($predicateArr as $i => $v) { | |
$i = substr($i, 1); | |
if (! isset($output[$i])) | |
$output[$i] = $data[$i]; | |
} | |
} | |
return $output; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A simple solution to sort multi-dimensional array using multiple sort criteria/properties, which may be in the form of dot notation. The direction of sort can also be defined per criterion/property.
Sample usage: