2

I've got an array as such:

$currentTerm = array(
  'name' => $term->name,
  'weight' => $term->weight
);

I'd like to sort the entire array by the weight key. I can't figure out how to accomplish this. Any thoughts or should I write a custom function for this?

P.S Some weights can be the same; so storing them as a key isn't an option. And it's multidimensional with a children key which is filled recursively the same way as above.

CaptainCarl
  • 3,411
  • 6
  • 38
  • 71

3 Answers3

5

You can create a custom sorting method usort().

It would work similarly to this:

usort($array, function($a,$b) {
    if($a->weight === $b->weight) return 0;
    return ($a->weight < $b->weight) ? -1 : 1;
});

If people from the PHP7 future come here, they can just use this (spaceships!):

usort($array, function($a,$b) {
    return $a->weight <=> $b->weight;
});

A full (and cumbersome) example for pre-PHP7 would be:

<?php
class Obj {
    public $name;
    public $weight;

    function __construct($name,$weight) {
        $this->name = $name;
        $this->weight = $weight;
    }
}
$array = array(
    new Obj("A",3),
    new Obj("B",10),
    new Obj("C",8),
);

usort($array, function($a,$b) {
    if($a->weight == $b->weight) return 0;
    return ($a->weight < $b->weight) ? -1 : 1;
});

print_r($array);

?>
Andrius
  • 5,934
  • 20
  • 28
  • I guess the function should also return 0 if weights are same. – Salman A Nov 06 '15 at 08:31
  • While it would probably make no difference in this case, it might in others. I've changed it, @SalmanA, thanks! – Andrius Nov 06 '15 at 08:35
  • With some tweaking with the multi dimensionality It worked out fine with this Usort. I didn't add the 0 return value because being the same weight doesn't mean it should be the first weight. Two times a weight of 5 after a weight of 4 doesn't mean the 5 should be infront. – CaptainCarl Nov 06 '15 at 08:49
  • The code has a little error. The question shows an associative array, but the example shows accessing properties of an object. It should be `return $a['weight'] <=> $b['weight'];` – Robert Sep 19 '21 at 17:49
1

Take a look at array_multisort()

$weight = array();
foreach ($currentTerm as $key => $row)
{
    $weight[$key] = $row['weight'];
}

then

array_multisort($weight, SORT_ASC, $currentTerm);

or

array_multisort($weight, SORT_DESC, $currentTerm);
Paul Denisevich
  • 2,329
  • 14
  • 19
0

You can try this code:

//define a comparison function
function cmp($a, $b) {
    if ($a['status'] == $b['status']) {
        return 0;
    }
    return ($a['status'] < $b['status']) ? -1 : 1;
}

usort($array, "cmp");
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Harsh Sanghani
  • 1,666
  • 1
  • 14
  • 32
  • when $array is associative array, this is the required syntax. In this example the array is sorted by the values of the `'status'` key – Robert Sep 19 '21 at 17:43
  • ... though for the reply to the original question, instead of `'status'` it should be `'weight'` – Robert Sep 19 '21 at 17:51