Skip to content

Instantly share code, notes, and snippets.

@msacket
Last active January 14, 2017 18:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msacket/c5bfc383c30b7e843e2c4d0b5f621014 to your computer and use it in GitHub Desktop.
Save msacket/c5bfc383c30b7e843e2c4d0b5f621014 to your computer and use it in GitHub Desktop.
PHP Multi-Sort Function - Sorts an array based on positional matches in other arrays.
<?php
/**
* Sorts an array based on matching multiple criteria.
* Given
* $array => ['big cat', 'small dog', 'big dog', 'small cat']
* $criteira =>[['dog','cat'], ['big','small']]
*
* Results: (biggest to smallest)
* ['big dog', 'small dog', 'big cat', 'small cat']
*
* @param array $array The array to be sorted
* @param array $criteria The criteria
* @param array $defaults Any default indexes.
*/
function sort_by_array(&$array, $criteria, $defaults=array()){
$cache = array();
// prepare the criteria by sorting them from longest to shortest
// maintaining the original key (index)
foreach($criteria as &$c){
uasort($c, function($a,$b){
return strlen($b) - strlen($a);
});
}
// define a function for returning the index matching the given str
// given: 'one' and ['zero', 'one', 'two'] returns 1
$findIndex = function($str, $values){
foreach($values as $index=>$value){
if( stripos($str, $value) !== FALSE ){
return $index;
}
}
return NULL;
};
// define a function to calculate a weighted value based on the criteria
// returns a value similar to: 2000-0000-3300 (one segment for each criteria)
$calculateValue = function($str) use ($criteria, $findIndex, $defaults, $cache){
if( !isset($cache[$str]) ){
$parts = array();
foreach($criteria as $i=>$c){
$parts[$i] = $findIndex($str, $c);
if( $parts[$i] === NULL ){
$parts[$i] = (isset($defaults[$i]) ? $defaults[$i] : 9999);
}
$parts[$i] = str_pad($parts[$i], 4, '0');
}
$cache[$str] = implode($parts, '-');
}
return $cache[$str];
};
// define our compare function
$compare = function($a, $b) use ($calculateValue){
$av = $calculateValue($a);
$bv = $calculateValue($b);
return $av > $bv;
};
// sort the array`
usort($array, $compare);
}
$animals = ['big cat', 'small dog', 'big dog', 'small cat'];
$sort_criteria = [['dog','cat'], ['big','small']];
sort_by_array($animals, $sort_criteria);
print_r($animals);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment