0

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?

Awais Qarni
  • 17,492
  • 24
  • 75
  • 137

2 Answers2

0

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
        )
)
arkascha
  • 41,620
  • 7
  • 58
  • 90
0

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!

Brian61354270
  • 8,690
  • 4
  • 21
  • 43