0

I have been trying to sort a keyed array by an object instance variable value contained within using usort() and it does not seem like the right tool to be using. Was hoping someone has some advice on sorting an object as shown below.

Thanks in advance!

$ary = array("apple" => object DatePrice ("date" => "2015-12-01", "price" => 3), 
               "orange" => object DatePrice ("date" => "2015-12-02", "price" => 4), 
               "banana" => object DatePrice ("date" => "2015-12-01", "price" => 0.50),
               "pear" => object DatePrice("date" => "2015-12-01", "price" => 1),
                );

Desired result:

$ary = array("orange" =>object DatePrice("date" => "2015-12-02", "price" => 4),
              "apple" => object DatePrice("date" => "2015-12-01", "price" => 3), 
               "pear" => object DatePrice("date" => "2015-12-01", "price" => 1),
                "banana" => object DatePrice("date" => "2015-12-01", "price" => 0.50));

Found this post: Sort array of objects by object fields

But I need to sort a keyed array of objects..

Community
  • 1
  • 1
AnchovyLegend
  • 12,139
  • 38
  • 147
  • 231
  • usort is the right one. Can you show your current attempt? – rjdown Dec 05 '15 at 20:16
  • 1
    I think [`uasort`](https://secure.php.net/manual/function.uasort.php) is more appropriate. – Yoshi Dec 05 '15 at 20:18
  • Ah yes, the keys, good call – rjdown Dec 05 '15 at 20:19
  • 1
    But note that you don't have any __objects__ here.... "object" has a very specific meaning, and this isn't it. What you have is a nested array, or an array of arrays – Mark Baker Dec 05 '15 at 20:27
  • you're right, edited the title – AnchovyLegend Dec 05 '15 at 20:29
  • @Mark Baker, I actually need the sorting of a keyed array by object instance variable value, see edited post – AnchovyLegend Dec 05 '15 at 20:36
  • 2
    @AnchovyLegend The sorting function (`uasort`) works agnositc of the value type, it's only concern is that the array keys should be kept. So only your comparison function should have any knowledge of the specialities of the array values (`DatePrice` in your case). What I'm trying to say, is that it's irrelevant what you're sorting, as long as the comparison function returns the appropriate result. – Yoshi Dec 05 '15 at 20:47
  • 1
    If you want your results to be an array of objects instead of an array of arrays, then you have two steps: `uasort()` and then an `array_walk()` to convert the "sub-arrays" to objects.... or do the `array_walk()` first, and then `uasort()` – Mark Baker Dec 05 '15 at 21:27

2 Answers2

2

Something like that...

uasort($ary, function ($a, $b) {
    return floatval($b['price']) - floatval($a['price']);
});

For objects it will not change a lot, it's just a function, check whatever you need here...

uasort($ary, function ($a, $b) {
    return floatval($b->price) - floatval($a->price);
});
Iurii Tkachenko
  • 3,106
  • 29
  • 34
  • You're ignoring the keys? $a['price'] and $b['price'] would be undefined without referencing the keys. – AnchovyLegend Dec 05 '15 at 20:20
  • Fixed my answer, then better to use `uasort` ;) – Iurii Tkachenko Dec 05 '15 at 20:23
  • Seems to be working, can you explain why this works? Why are you getting the difference between $b and $a instead of the checking for greater than / less than ? – AnchovyLegend Dec 05 '15 at 20:27
  • @AnchovyLegend Returning the difference works sometimes (with ints), because php is only interested in greater/smaller/equal to 0, but in your case with floats I would avoid it, use the traditional <> *way* when handling floats. – Yoshi Dec 05 '15 at 20:30
  • The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second. _Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal._ – Iurii Tkachenko Dec 05 '15 at 20:30
  • @YuriTkachenko just -1, 0 or 1 is typical, not the actual difference. – rjdown Dec 05 '15 at 20:41
  • What if I am sorting a keyed array of objects? See edited post – AnchovyLegend Dec 05 '15 at 20:42
  • Didn't work on a keyed array with objects, getting a "Trying to get property of non-object" error, when trying to $a->price – AnchovyLegend Dec 05 '15 at 21:20
  • @AnchovyLegend Just replace `$a->price` with proper way to get a price from your DatePrice object. Same for `$b->price` ;) – Iurii Tkachenko Dec 05 '15 at 21:23
  • Thanks Yuri, with slight tweaking, this worked like a charm ;) – AnchovyLegend Dec 05 '15 at 21:37
0

take look at array_multisort(). with that method you can sort (multi-dimensional) arrays based on its key and specify its sort order.

PAlphen
  • 186
  • 1
  • 9