skip to Main Content

Hi I have an array that looks like this

array[
   0 => array[
         'id'  => 1,
         'name' => 'Test 1'
         'classId' => 3
       ],
  1 => array[
         'id'  => 1,
         'name' => 'Test 1'
         'classId' => 15
       ],
  2 => array[
         'id'  => 1,
         'name' => 'Test 1'
         'classId' => 17
       ],
]

And I have another array that contains classIds like:

 classIds = [15, 17, 3]

And I want to sort my array based on classIds

I can do a a double loop to compare it. I am just wondering is there anyother way to get it done?

2

Answers


  1. Actually one loop i enough:

    <?php
    $order = [15, 17, 3];
    $input = [
      [
        'id'  => 1,
        'name' => 'Test 1',
        'classId' => 3,
      ],
      [
        'id'  => 1,
        'name' => 'Test 1',
        'classId' => 15,
      ],
      [
        'id'  => 1,
        'name' => 'Test 1',
        'classId' => 17,
      ],
    ];
    $output = [];
    array_walk($input, function($entry) use ($order, &$output) {
      $output[array_search($entry['classId'], $order)] = $entry;
    });
    ksort($output);
    print_r($output);
    

    In case you consider array_search(...) also a "loop" (though it internally works different), that would be an alternative which produces the same output:

    <?php
    $order = array_flip([15, 17, 3]);
    $input = array_values([
      [
        'id'  => 1,
        'name' => 'Test 1',
        'classId' => 3,
      ],
      [
        'id'  => 1,
        'name' => 'Test 1',
        'classId' => 15,
      ],
      [
        'id'  => 1,
        'name' => 'Test 1',
        'classId' => 17,
      ],
    ]);
    $output = [];
    array_walk($input, function($entry, $index) use ($order, &$output) {
      $output[$order[$entry['classId']]] = $entry;
    });
    ksort($output);
    print_r($output);
    

    The output of both approaches is:

    Array
    (
        [0] => Array
            (
                [id] => 1
                [name] => Test 1
                [classId] => 15
            )
        [1] => Array
            (
                [id] => 1
                [name] => Test 1
                [classId] => 17
            )
        [2] => Array
            (
                [id] => 1
                [name] => Test 1
                [classId] => 3
            )
    )
    
    Login or Signup to reply.
  2. You can sort the array directly and in-place using usort and an anonymous comparison function that retrieves the target indices from $classIds.

    Given

    <?php
    $arr = array(
       0 => array(
             'id'  => 1,
             'name' => 'Test 1',
             'classId' => 3
           ),
      1 => array(
             'id'  => 1,
             'name' => 'Test 1',
             'classId' => 15
           ),
      2 => array(
             'id'  => 1,
             'name' => 'Test 1',
             'classId' => 17
           ),
    );
    $classIds = [15, 17, 3];
    

    you can sort $arr with

    // Create assoc array mapping classIds to their desired sorted position.
    $classIdsOrder = array_combine($classIds, range(0, count($classIds)-1));
    
    // Sort $arr according to the 'classId' order described by $classIdsOrder
    usort($arr, function ($left, $right) use ($classIdsOrder) {
        return $classIdsOrder[$left['classId']] <=> $classIdsOrder[$right['classId']];
    });
    
    print_r($arr);
    

    which outputs

    Array
    (
        [0] => Array
            (
                [id] => 1
                [name] => Test 1
                [classId] => 15
            )
    
        [1] => Array
            (
                [id] => 1
                [name] => Test 1
                [classId] => 17
            )
    
        [2] => Array
            (
                [id] => 1
                [name] => Test 1
                [classId] => 3
            )
    
    )
    

    Try it online!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search