0

PHP Multidimensional array custom sort.

Sort should be based on values in field [position] A person can have multiple positions (see the special case listed below).

Array
(
    [0] => Array
    (
        [position] => Array
            (
                [0] => Secretary
            )
    )
)

I want the array to be ordered on position values as

  1. General Secretary
  2. President
  3. Treasurer
  4. Secretary
  5. Committee Member

Special case for the below array, it should be the first array. Because this person is "General Secretary"

[2] => Array
(
    [person_id] => 51136
    [position] => Array
        (
            [0] => General Secretary
            [1] => Committee Member
        )

    [person_name] => Person 1
)

Example input data

Array
(
    [0] => Array
    (
        [person_id] => 22180
        [position] => Array
            (
                [0] => Secretary
            )
        [person_name] => Person 1
    )

    [1] => Array
    (
        [person_id] => 51135
        [position] => Array
            (
                [0] => President
            )
        [person_name] => Person 2
    )

    [2] => Array
    (
        [person_id] => 51136
        [position] => Array
            (
                [0] => General Secretary
                [1] => Committee Member
            )

        [person_name] => Person 3
    )

    [3] => Array
    (
        [person_id] => 44141
        [position] => Array
            (
                [0] => Treasurer 
            )

        [person_name] => Person 4
    )

    [4] => Array
    (
        [person_id] => 51137
        [position] => Array
            (
                [0] => Committee Member
            )
        [person_name] => Person 5
    )
)

Output required

Array
(
    [0] => Array
    (
        [person_id] => 51136
        [position] => Array
            (
                [0] => General Secretary
                [1] => Committee Member
            )

        [person_name] => Person 3
    )
    [1] => Array
    (
        [person_id] => 51135
        [position] => Array
            (
                [0] => President
            )
        [person_name] => Person 2
    )
    [2] => Array
    (
        [person_id] => 44141
        [position] => Array
            (
                [0] => Treasurer 
            )

        [person_name] => Person 4
    )
    [3] => Array
    (
        [person_id] => 22180
        [position] => Array
            (
                [0] => Secretary
            )
        [person_name] => Person 1
    )
    [4] => Array
    (
        [person_id] => 51137
        [position] => Array
            (
                [0] => Committee Member
            )
        [person_name] => Person 5
    )
)
Mohamed Navas
  • 592
  • 7
  • 16
  • See: http://stackoverflow.com/questions/2699086/sort-multidimensional-array-by-value-2 – shapeshifter Oct 18 '12 at 07:07
  • check this out... http://stackoverflow.com/questions/96759/how-do-i-sort-a-multidimensional-array-in-php – bipen Oct 18 '12 at 07:09
  • I can't use descending or ascending type. see the portion in question **"I want the array to be ordered on position values as"** – Mohamed Navas Oct 18 '12 at 07:15
  • You can still use `usort()`, just compare two person by `array_search($position,array(5=>"General Secretary",4=>"President"...))`. – Passerby Oct 18 '12 at 07:19

2 Answers2

1

Alright, I make this out.

You can still use usort() instead of re-inventing the wheel. Just compare two person by the position like array_search($position,$pos_array).

function sortByPosition($ps)
{
    $pos=array(0=>"General Secretary",1=>"President",2=>"Treasurer",3=>"Secretary",4=>"Committee Member");
    usort($ps,function($p1,$p2) use ($pos){
        $lvl1=count($pos);
        $lvl2=count($pos);
        foreach($p1["position"] as $position)
        {
            $lvl1=min(array_search($position,$pos),$lvl1);
        }
        foreach($p2["position"] as $position)
        {
            $lvl2=min(array_search($position,$pos),$lvl2);
        }
        return $lvl1-$lvl2;
    });
    return $ps;
}

Test:

$arr=Array(Array("person_id" => 22180,"position" => Array("Secretary"),"person_name" => "Person 1"), Array("person_id" => 51135,"position" => Array("President"),"person_name" => "Person 2"), Array("person_id" => 51136,"position" => Array("General Secretary","Committee Member"),"person_name" => "Person 3"), Array("person_id" => 44141,"position" => Array("Treasurer"),"person_name" => "Person 4"), Array("person_id" => 51137,"position" => Array("Committee Member"),"person_name" => "Person 5"));
print_r(sortByPosition($arr));

Outputs:

Array
(
    [0] => Array
        (
            [person_id] => 51136
            [position] => Array
                (
                    [0] => General Secretary
                    [1] => Committee Member
                )

            [person_name] => Person 3
        )

    [1] => Array
        (
            [person_id] => 51135
            [position] => Array
                (
                    [0] => President
                )

            [person_name] => Person 2
        )

    [2] => Array
        (
            [person_id] => 44141
            [position] => Array
                (
                    [0] => Treasurer
                )

            [person_name] => Person 4
        )

    [3] => Array
        (
            [person_id] => 22180
            [position] => Array
                (
                    [0] => Secretary
                )

            [person_name] => Person 1
        )

    [4] => Array
        (
            [person_id] => 51137
            [position] => Array
                (
                    [0] => Committee Member
                )

            [person_name] => Person 5
        )

)
Passerby
  • 9,715
  • 2
  • 33
  • 50
0

You could implement Quicksort, or any other sorting algorithm, and just make sure the comparison takes place on the right variable.

http://en.wikipedia.org/wiki/Quicksort

From Wiipedias pseudocode you could du this by changing the 7th line to just check the position parameter of your arrays.

function quicksort('array')
      if length('array') ≤ 1
          return 'array'  // an array of zero or one elements is already sorted
      select and remove a pivot value 'pivot' from 'array'
      create empty lists 'less' and 'greater'
      for each 'x' in 'array'
          if 'x' ≤ 'pivot' then append 'x' to 'less' // change to x['position'] and pivot['position']
          else append 'x' to 'greater'
      return concatenate(quicksort('less'), 'pivot', quicksort('greater')) // two recursive calls
Andreas Hagen
  • 2,335
  • 2
  • 19
  • 34