Sorting an array of an array of objects in PHP by

2019-01-23 20:24发布

问题:

Basically I have a setup like the following:

Array ( 
[0] => Array ( [0] => stdClass Object ( [nid] => 1 [title] => title1 [uid] => 1 [parent] => 0 [weight] => -15 [name] => name1 [value] => 0 )
               [1] => stdClass Object ( [nid] => 2 [title] => title2 [uid] => 1 [parent] => 0 [weight] => -7 [name] => name2 [value] => 100 )
               [2] => stdClass Object ( [nid] => 3 [title] => title3 [uid] => 2 [parent] => 0 [weight] => -1 [name] => name3 [value] => 0 )
               [3] => stdClass Object ( [nid] => 4 [title] => title4 [uid] => 2 [parent] => 0 [weight] => 1 [name] => name4 [value] => 80 )
              )
  )

What I need is a way to sort all the arrays inside the parent array by the [value] key in the Object. I've been trying for about 2 days now with usort and different methods but I just can't seem to get my head around it. The [value] key will range anywhere from 0 to 100 and I need all of the arrays sorted in decreasing order (IE: 100 down to 0).

回答1:

Use usort:

function cmp($a, $b) {
  if ($a->value == $b->value) {
    return 0;
  } else {
    return $a->value < $b->value ? 1 : -1; // reverse order
  }
}

usort($arr, 'cmp');


回答2:

100% stolen from the 1st answer on this page. http://us.php.net/manual/en/function.array-multisort.php
But this is what I was looking for.

multisort an Array of Objects:

example object [$object with array of objects]: (class: test) 
---------------------------------- 

test Object (
  [Artikel] => Array (
      [0] => test Object (
            [id] => 1
            [title] => CCCC
         )
      [1] => test Object (
            [id] => 2
            [title] => AAAA
         )
      [2] => test Object (
            [id] => 3
            [title] => DDDD
         )
      [3] => test Object (
            [id] => 4
            [title] => BBBB
         )
   )
)

---------------------------------- 

Simple PHP function: sort_arr_of_obj()

<?php 
// -------------------------------------- 

/* 
* -------- function arguments -------- 
*   $array ........ array of objects
*   $sortby ....... the object-key to sort by
*   $direction ... 'asc' = ascending
* --------
*/

function sort_arr_of_obj($array, $sortby, $direction='asc') {

    $sortedArr = array();
    $tmp_Array = array();

    foreach($array as $k => $v) {
        $tmp_Array[] = strtolower($v->$sortby);
    }

    if($direction=='asc'){
        asort($tmp_Array);
    }else{
        arsort($tmp_Array);
    }

    foreach($tmp_Array as $k=>$tmp){
        $sortedArr[] = $array[$k];
    }

    return $sortedArr;

}


// -------------------------------------- 
?>

example call: 
---------------------------------- 

<?php 

$sorted->Artikel = sort_arr_of_obj($object->Artikel,'title','asc');

?>

example result: $sorted (class: test) 
---------------------------------- 

test Object (
  [Artikel] => Array (
      [0] => test Object (
            [id] => 2
            [title] => AAAA
         )
      [1] => test Object (
            [id] => 4
            [title] => BBBB
         )
      [2] => test Object (
            [id] => 1
            [title] => CCCC
         )
      [3] => test Object (
            [id] => 3
            [title] => DDDD
         )

   )
)


回答3:

A way to do this is to separate the value array from the array of objects, and thus, creating two arrays. You can then use array_multisort to sort the array of objects according to the other array. Here's an example:

<?php
$array1 = $objectvalues
$array2 = array(ObjectWithNid1, ObjectWithNid2, ObjectWithNid3, ObjectWithNid4);
array_multisort($array1, $array2);
?>

You can use a foreach to loop the array one time and create a new array with the corresponding [value] key:

<?php
foreach( $arraywithobjects as $obj )
{
    $objectvalues[] = $obj->getValue();
}
?>

This will get the Object's value and insert it into another array which you can use with the multisort.

In the end, your code will look like this:

<?php
foreach( $arraywithobjects as $obj )
{
    $objectvalues[] = $obj->getValue();
}
$array2 = array(ObjectWithNid1, ObjectWithNid2, ObjectWithNid3, ObjectWithNid4);
array_multisort($objectvalues, $array2);
?>

The first array in the array_multisort field should be the array you're using to sort the second array.

You can also add other sorting method for this. You can read them here: link text



回答4:

function cmp($a, $b) {
    return $b->value - $a->value;
}

$ary[0] = usort($ary[0], "cmp");

In order to sort an array based on anything other than simple value or key, you need to use the usort function and supply your own comparison. Comparison functions must be defined such that if $a comes before $b, a positive value is returned and a negative one if $b comes before $a (or zero if they are equal). As you are comparing based on number values and you want a reverse sort, the simplest way of doing this is to subtract the 'value' of $a from the value of $b.



回答5:

I could be wrong, but I believe I did something like this using asort() (or asort()). It was in a search function, where I needed to sort a two-dimensional array filled with indices and timestamps.

I'm not sure if it will work in your case, and I did it long ago. Maybe it will get you started though, good luck.