Skip to content
Advertisement

How to sort a PHP array with key/value pair by custom defined order of the key value? [closed]

I’ve looked for various sorting function but quite couldn’t find what I am looking for.

Here’s my current array result.

  0 =>
  array(
    'member_reference_identifier' => '001',
    'user_status' => 'Hold',
    'is_primary' => 'true',
  ),
  1 =>
  array(
    'member_reference_identifier' => '002',
    'user_status' => 'Banned',
    'is_primary' => 'true',
  ),
  2 =>
  array(
    'member_reference_identifier' => '003',
    'user' => 'Banned',
    'is_primary' => 'true',
  ),
  3 =>
  array(
    'member_reference_identifier' => '004',
    'user_status' => 'Active',
    'is_primary' => 'false',
  ),
  4 =>
  array(
    'member_reference_identifier' => '005',
    'user_status' => 'Active',
    'is_primary' => 'true',
  ),
  5 =>
  array(
    'member_reference_identifier' => '006',
    'user_status' => 'Hold',
    'is_primary' => 'true',
  ),
  6 =>
  array(
    'member_reference_identifier' => '007',
    'user_status' => 'Banned',
    'is_primary' => 'true',
  ),
)

I am looking to show the primary results first and in that, I want to have sorted order: Active > Hold > Banned.

Here’s what I am expecting:

  4 =>
  array(
    'member_reference_identifier' => '005',
    'user_status' => 'Active',
    'is_primary' => 'true',
  ),

  0 =>
  array(
    'member_reference_identifier' => '001',
    'user_status' => 'Hold',
    'is_primary' => 'true',
  ),
  5 =>
  array(
    'member_reference_identifier' => '006',
    'user_status' => 'Hold',
    'is_primary' => 'true',
  ),
  1 =>
  array(
    'member_reference_identifier' => '002',
    'user_status' => 'Banned',
    'is_primary' => 'true',
  ),
  2 =>
  array(
    'member_reference_identifier' => '003',
    'user_status' => 'Banned',
    'is_primary' => 'true',
  ),

  6 =>
  array(
    'member_reference_identifier' => '007',
    'user_status' => 'Banned',
    'is_primary' => 'true',
  ),
  3 =>
  array(
    'member_reference_identifier' => '004',
    'user_status' => 'Active',
    'is_primary' => 'false',
  ),

)

Even though the last object is active, it’s at last because is_primary is false.

Adding more details to make the question bit more focused: I was able to determine the super brute force solution splitting my main array into multiple arrays. Sorting them individually and joining them again. But, that was such an expensive operation given the large dataset I was dealing with, probably millions of objects in an array. I am mainly looking for something optimal.

Advertisement

Answer

try uasort – it’ll sort an array with a user-defined comparison function and maintain index association:

<?php
        $x = [
        0 =>[
                'member_reference_identifier' => '001',
                'user_status' => 'Hold',
                'is_primary' => 'true',
                ],
        1 => [
                'member_reference_identifier' => '002',
                'user_status' => 'Banned',
                'is_primary' => 'true',
                ],
        2 => [
                'member_reference_identifier' => '003',
                'user_status' => 'Banned',
                'is_primary' => 'true',
                ],
        3 =>[
                'member_reference_identifier' => '004',
                'user_status' => 'Active',
                'is_primary' => 'false',
                ],
        4 => [
                'member_reference_identifier' => '005',
                'user_status' => 'Active',
                'is_primary' => 'true',
                ],
        5 => [
                'member_reference_identifier' => '006',
                'user_status' => 'Hold',
                'is_primary' => 'true',
        ],
        6 => [
                'member_reference_identifier' => '007',
                'user_status' => 'Banned',
                'is_primary' => 'true',
                ],
        ];


        function sorter($a,$b){
                $states = ['Active'=>0,'Hold'=>1,'Banned'=>2];
                if ($a['is_primary'] == 'true' && $b['is_primary']=='false') return -1;
                if ($a['is_primary'] == 'false' && $b['is_primary']=='true') return 1;
                return $states[$a['user_status']]<=>$states[$b['user_status']];
        }
        uasort($x,'sorter');
        print_r($x);

PS your array was inconsistent – i’ve unified keys user. account_status to user_status.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement