fork(2) download
  1. <?php
  2.  
  3. class SortDirection {
  4. const Ascending = 1;
  5. const Descending = -1;
  6. }
  7.  
  8. interface Filter {
  9. public function filter($item);
  10. }
  11.  
  12. interface Comparator {
  13. public function compare($a, $b);
  14. }
  15.  
  16. class MultipleKeyValueFilter implements Filter {
  17. protected $kvPairs;
  18.  
  19. public function __construct($kvPairs) {
  20. $this->kvPairs = $kvPairs;
  21. }
  22.  
  23. public function filter($item) {
  24. $result = true;
  25.  
  26. foreach ($this->kvPairs as $key => $value) {
  27. if ($item[$key] !== $value)
  28. $result &= false;
  29. }
  30.  
  31. return $result;
  32. }
  33. }
  34.  
  35. class KeyComparator implements Comparator {
  36. protected $direction;
  37. protected $transform;
  38. protected $key;
  39.  
  40. public function __construct($key, $direction = SortDirection::Ascending, $transform = null) {
  41. $this->key = $key;
  42. $this->direction = $direction;
  43. $this->transform = $transform;
  44. }
  45.  
  46. public function compare($a, $b) {
  47. $a = $a[$this->key];
  48. $b = $b[$this->key];
  49.  
  50. if ($this->transform) {
  51. $a = $this->transform($a);
  52. $b = $this->transform($b);
  53. }
  54.  
  55. return $a === $b ? 0 : (($a > $b ? 1 : -1) * $this->direction);
  56. }
  57. }
  58.  
  59. class MultipleKeyComparator implements Comparator {
  60. protected $keys;
  61.  
  62. public function __construct($keys) {
  63. $this->keys = $keys;
  64. }
  65.  
  66. public function compare($a, $b) {
  67. $result = 0;
  68.  
  69. foreach ($this->keys as $comparator) {
  70. if ($comparator instanceof KeyComparator) {
  71. $result = $comparator->compare($a, $b);
  72.  
  73. if ($result !== 0) return $result;
  74. }
  75. }
  76.  
  77. return $result;
  78. }
  79. }
  80.  
  81.  
  82. $array = array (
  83. '1' => array ('type' => 'blah2', 'category' => 'cat2', 'exp_range' => 'this_week' ),
  84. '2' => array ('type' => 'blah1', 'category' => 'cat1', 'exp_range' => 'this_week' ),
  85. '3' => array ('type' => 'blah1', 'category' => 'cat2', 'exp_range' => 'next_week' ),
  86. '4' => array ('type' => 'blah1', 'category' => 'cat1', 'exp_range' => 'next_week' )
  87. );
  88.  
  89. $comparator = new MultipleKeyComparator(array(
  90. new KeyComparator('type'),
  91. new KeyComparator('exp_range')
  92. ));
  93.  
  94. usort($array, array($comparator, 'compare'));
  95.  
  96. echo "Sorted by multiple fields\n";
  97. print_r($array);
  98.  
  99. $filter = new MultipleKeyValueFilter(array(
  100. 'type' => 'blah1'
  101. ));
  102.  
  103. echo "Filtered by multiple fields\n";
  104. print_r(array_filter($array, array($filter, 'filter')));
Success #stdin #stdout 0.01s 20568KB
stdin
Standard input is empty
stdout
Sorted by multiple fields
Array
(
    [0] => Array
        (
            [type] => blah1
            [category] => cat1
            [exp_range] => next_week
        )

    [1] => Array
        (
            [type] => blah1
            [category] => cat2
            [exp_range] => next_week
        )

    [2] => Array
        (
            [type] => blah1
            [category] => cat1
            [exp_range] => this_week
        )

    [3] => Array
        (
            [type] => blah2
            [category] => cat2
            [exp_range] => this_week
        )

)
Filtered by multiple fields
Array
(
    [0] => Array
        (
            [type] => blah1
            [category] => cat1
            [exp_range] => next_week
        )

    [1] => Array
        (
            [type] => blah1
            [category] => cat2
            [exp_range] => next_week
        )

    [2] => Array
        (
            [type] => blah1
            [category] => cat1
            [exp_range] => this_week
        )

)