-1

I have an array similar to the one below

I need to sort this array into a certain order eg. How can I custom order by the name property into this order C2, C1, C3 for example?

   array(11) {
      [0]=>
      object(stdClass)#1569 (8) {
        ["name"]=>
        string(36) "C1"
      }
      [1]=>
      object(stdClass)#1589 (8) {
        ["name"]=>
        string(36) "C2"
      }
      [2]=>
      object(stdClass)#1599 (8) {
        ["name"]=>
        string(36) "C3"
      }
    }
Peter
  • 1
  • 2
  • 4
    Possible duplicate of [Rearrange an array of objects by a custom order in PHP](https://stackoverflow.com/questions/13692687/rearrange-an-array-of-objects-by-a-custom-order-in-php) – mickmackusa May 14 '18 at 23:01
  • Please search the myriad of `sorting` pages on StackOverflow before posting a question. – mickmackusa May 14 '18 at 23:02
  • It looks like your original array has 11 objects in it. What is your expected behavior with the remaining objects? Leave them in their original location? Is this coming from a mysql resultset? a json decoded string? – mickmackusa May 15 '18 at 20:19

1 Answers1

2

Define your custom order in an array.

$order = ['C2' => 0, 'C1' => 1, 'C3' => 2];

Then use that array in the comparison callback to usort.

usort($objects, function($ob1, $ob2) use ($order) {
    return $order[$ob1->name] <=> $order[$ob2->name];
});

If it's possible that some of the objects won't have a name property, or that they may have name properties that aren't included in the custom order, we can set default values so that any of those will be sorted to the end. (This will prevent "Undefined Index" and "Undefined Property" notices as well.)

usort($objects, function($ob1, $ob2) use ($order) {
    return ($order[($ob1->name ?? '')] ?? end($order) + 1)
       <=> ($order[($ob2->name ?? '')] ?? end($order) + 1);
});
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
  • Declaring the `$order` lookup in a "flipped" structure provides an improvement to the suggested code @ [How can I sort arrays and data in PHP?](https://stackoverflow.com/a/17364128/2943403) because it avoids iterated `array_search()` calls. It may be a micro-optimization to call `$order` using `static` inside of the function if it is not dynamically delivered to `usort()` -- of course, I don't know if that will work with the OP's project design. A good, clean answer @Don't – mickmackusa May 14 '18 at 23:35
  • I suppose another reasonable acknowledgement would be: Is it possible that a particular `$order` key will not be represented? We don't want to generate Notices when `$order[$ob->name]` does not exist. If this is a reasonable concern, then `isset()` will be necessary OR using an un-flipped lookup array with `array_search()` makes sense too. – mickmackusa May 15 '18 at 03:06
  • @mickmackusa thanks for the critique. I agree we don't want notices, but also importantly, if an `$ob->name` is undefined or missing in the custom order, the sort order becomes difficult to predict for those items. I updated the answer to handle that case. – Don't Panic May 15 '18 at 16:25