Posted By

mattnicholson on 01/22/15


Tagged

php sort array filter


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

jbyerson


Sort & query multi-dimensional arrays by properties


 / Published in: PHP
 

URL: https://github.com/mattnicholson/DataList

Sort & query arrays in PHP. Sort multi dimensional arrays by object properties and filter the array by specific criteria.

Documentation: https://github.com/mattnicholson/DataList

  1. <?
  2.  
  3. /*
  4.  
  5. DataList
  6. ----------------------------------------------
  7. Query and Sort multi-dimensional arrays in PHP
  8.  
  9. @author Matt Nicholson <[email protected]>
  10. @website https://github.com/mattnicholson/DataList.git
  11.  
  12. */
  13.  
  14. class DataList{
  15.  
  16. public $list;
  17. public $sortable;
  18. public $subset;
  19. public $wheres;
  20.  
  21. function __construct($list = array())
  22. {
  23. $this->list = $list;
  24. $this->sortable = $list;
  25. $this->subset = array();
  26. $this->wheres = array();
  27. }
  28.  
  29. function where($prop,$rule){
  30.  
  31. $subset = (!sizeof($this->wheres)) ? $this->list : $this->subset;
  32. $this->subset = array();
  33.  
  34. foreach($subset as $item):
  35.  
  36. if($this->match($item,$prop,$rule)) $this->subset[] = $item;
  37.  
  38. endforeach;
  39.  
  40. $this->wheres[] = array($prop,$rule);
  41.  
  42. }
  43.  
  44. function match($item,$prop,$rule){
  45.  
  46.  
  47. $this->wheres[] = $rule;
  48. $prop = $this->getRawValue($item,$prop);
  49. $type = gettype($prop);
  50.  
  51. switch($type):
  52.  
  53. case 'string':
  54.  
  55. $match = preg_match('/'.$rule.'/',$prop);
  56.  
  57. break;
  58. case 'object':
  59.  
  60. if(get_class($prop) == 'DateTime'):
  61. $value = $prop->getTimestamp();
  62.  
  63.  
  64. $match = eval('return ($value '.$rule.');');
  65.  
  66.  
  67. else:
  68.  
  69. $value = 0;
  70. endif;
  71.  
  72. break;
  73.  
  74. case 'integer' :
  75.  
  76. $value = $prop;
  77. $match = eval('return ($value '.$rule.');');
  78.  
  79. break;
  80. default:
  81. $match = 0;
  82. break;
  83.  
  84. endswitch;
  85.  
  86. return $match;
  87.  
  88. }
  89.  
  90. function find(){
  91.  
  92. $this->sortable = (!sizeof($this->wheres)) ? $this->list : $this->subset;
  93. $this->subset = array();
  94. $this->wheres = array();
  95. return $this->sortable;
  96.  
  97. }
  98.  
  99. function all(){
  100.  
  101. $this->sortable = $this->list;
  102. $this->subset = array();
  103. return $this->sortable;
  104.  
  105.  
  106. }
  107.  
  108. function length(){
  109.  
  110. return sizeof($this->sortable);
  111.  
  112. }
  113.  
  114. function sort($props=null,$order='ASC'){
  115.  
  116. $i = 0;
  117. $arr = array();
  118.  
  119. // Allow a string to be supplied
  120. if(gettype($props) == 'string') $props = array($props);
  121. if(!is_array($props)) $props = array();
  122.  
  123.  
  124. foreach($this->sortable as $item):
  125.  
  126. $k = $this->makeSortKey($item,$props);
  127.  
  128. // Add a unique counter to the end
  129. $unique = $this->padValue($i);
  130. $k = $k.$unique;
  131.  
  132. $arr[$k] = $item;
  133.  
  134. $i++;
  135.  
  136. endforeach;
  137.  
  138. switch($order):
  139. case 'DESC':
  140. krsort($arr);
  141. break;
  142.  
  143. default:
  144. ksort($arr);
  145. break;
  146. endswitch;
  147.  
  148. return $arr;
  149.  
  150.  
  151. }
  152.  
  153. function makeSortKey($item,$props){
  154.  
  155. $i = 0;
  156.  
  157. if(sizeof($props) == 1) :
  158. $k = $this->getSortablePropValue($item,$props[0]);
  159. else:
  160. $k = "";
  161.  
  162. foreach($props as $prop):
  163.  
  164. $value = $this->getSortablePropValue($item,$prop);
  165. $k = $k.$value;
  166.  
  167. $i++;
  168.  
  169. endforeach;
  170.  
  171.  
  172.  
  173. endif;
  174.  
  175. return $k;
  176.  
  177. }
  178.  
  179. function getNestedProperty($item,$prop){
  180.  
  181. $levels = explode('->',$prop);
  182.  
  183. $i = $item;
  184.  
  185.  
  186.  
  187. foreach($levels as $level):
  188.  
  189. $i = $i->{$level};
  190. if(is_array($i)) $i = (object) $i;
  191. endforeach;
  192.  
  193. return $i;
  194.  
  195. }
  196.  
  197. function getRawValue($item,$prop){
  198.  
  199. if(is_array($item)) $item = (object) $item;
  200.  
  201. if(strstr($prop,'->')):
  202. $prop = $this->getNestedProperty($item,$prop);
  203. else:
  204. $prop = $item->{$prop};
  205. endif;
  206.  
  207. if(preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})$/',$prop)) $prop = new DateTime($prop);
  208.  
  209. return $prop;
  210. }
  211.  
  212. function getSortablePropValue($item,$prop){
  213.  
  214. $prop = $this->getRawValue($item,$prop);
  215.  
  216. $type = gettype($prop);
  217. $dir = STR_PAD_LEFT;
  218. $pad = 30;
  219. switch($type):
  220.  
  221. case 'string':
  222. $dir = STR_PAD_RIGHT;
  223. $pad = 100;
  224. $value = preg_replace('/[^a-z0-9]/','',strtolower($prop));
  225. break;
  226. case 'object':
  227.  
  228. if(get_class($prop) == 'DateTime'):
  229. $value = $prop->getTimestamp();
  230. else:
  231. $value = 0;
  232. endif;
  233.  
  234. break;
  235.  
  236. case 'integer':
  237. $value = $prop;
  238. break;
  239.  
  240. default:
  241. $value = 0;
  242. break;
  243.  
  244. endswitch;
  245.  
  246. return $this->padValue($value,$pad,$dir);
  247.  
  248. }
  249.  
  250. function getPropValue($item,$prop,$sortable){
  251.  
  252. if(strstr($prop,'->')):
  253. $prop = $this->getNestedProperty($item,$prop);
  254. else:
  255. $prop = $item->{$prop};
  256. endif;
  257.  
  258. $type = gettype($prop);
  259. $dir = STR_PAD_LEFT;
  260. switch($type):
  261.  
  262. case 'string':
  263. $dir = STR_PAD_RIGHT;
  264. $value = preg_replace('/[^a-z0-9]/','',strtolower($prop));
  265. break;
  266. case 'object':
  267.  
  268. if(get_class($prop) == 'DateTime'):
  269. $value = $prop->getTimestamp();
  270. else:
  271. $value = 0;
  272. endif;
  273.  
  274. break;
  275.  
  276. case 'integer':
  277. $value = $prop;
  278. break;
  279.  
  280. default:
  281. $value = 0;
  282. break;
  283.  
  284. endswitch;
  285.  
  286. return $this->padValue($value,100,$dir);
  287.  
  288.  
  289.  
  290. }
  291.  
  292. function padValue($value,$pad=10,$dir = STR_PAD_LEFT){
  293.  
  294. return str_pad($value, $pad, "0", $dir);
  295.  
  296. }
  297.  
  298.  
  299. }
  300. ?>

Report this snippet  

You need to login to post a comment.