Last active
January 14, 2017 18:06
-
-
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.
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 | |
/** | |
* 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