1

I have array $data containing data about animals. I would like to sort this array by child element:

source array ($data):
    Array (
     [0] => (
      'name' => 'Leo'
      'type' => 'cat'
     )
     [1] => (
      'name' => 'Max'
      'type' => 'dog'
     )
     [2] => (
      'name' => 'Elsa'
      'type' => 'fish'
     )
     ...
    )

priority array ($priority)
$priority = [
            'fish', 'dog', 'cat',
        ];

I would like to sort source array using priority array. I tried:

sort($data, function (int $item1, int $item2) use($priority) {
            foreach($priority as $key => $value) {
                if($item1 == $value)
                {
                    return 0;
                    break;
                }

                if($item2 == $value)
                {
                    return 1;
                    break;
                }
            }

            return 0;
        });
Martin
  • 29
  • 3
  • _Warning: sort() expects parameter 2 to be int_ – AbraCadaver Jul 15 '19 at 14:08
  • Your approach makes rather little sense, by returning 0 in the first case you pretend that both items have the _same_ sorting order, which is not necessarily the case. I think instead of that foreach loop, you should rather use `array_search` for both values, and return the difference of the two found indexes. (Make sure you handle the case that this returns `false` as well though, if that could occur with your actual data.) – misorude Jul 15 '19 at 14:14
  • @Martin Is any `type` placed in the first array only once? – splash58 Jul 15 '19 at 14:22

1 Answers1

1

You can use usort with a custom compare function, like so:

<?php

$arr = array(
    0 => array(
      'name' => 'Leo',
      'type' => 'cat'
    ),
    1 => array(
      'name' => 'Max',
      'type' => 'dog'
    ),
    2 => array(
      'name' => 'Elsa',
      'type' => 'fish'
    )
);

$priority = array('fish', 'dog', 'cat');

usort($arr, function($a, $b) use($priority) { 
    return array_search($a['type'], $priority) <=> array_search($b['type'], $priority);
});

var_dump($arr);

How this works: usort accepts a custom compare function, you can pass it the priority array, then use the spaceship operator to compare the value indexes in priority.

Try it out: http://sandbox.onlinephpfunctions.com/code/03fdfa61b1bd8b0b84e5f08ab11b6bc90eeaef4a