Search code examples
phparrayssubstringdelimiterarray-multisort

PHP multisort on array field containing underscore


I have an array like this:

$data[] = array('ALT_ID' => '202143_N', 'bmi' => 2.5);
$data[] = array('ALT_ID' => '202144_P', 'bmi' => 1.2);
$data[] = array('ALT_ID' => '202145_N', 'bmi' => 6.6);
$data[] = array('ALT_ID' => '202146_P', 'bmi' => 3.6);
$data[] = array('ALT_ID' => '202147_N', 'bmi' => 7.6);
$data[] = array('ALT_ID' => '202148_P', 'bmi' => 8.6);

How to sort on the ALT_ID (N to P) and bmi (low to high) to get an array like this:

array (
array('ALT_ID' => '202143_N', 'bmi' => 2.5),
array('ALT_ID' => '202145_N', 'bmi' => 6.6),
array('ALT_ID' => '202147_N', 'bmi' => 7.6),
array('ALT_ID' => '202144_P', 'bmi' => 1.2),
array('ALT_ID' => '202146_P', 'bmi' => 3.6),
array('ALT_ID' => '202148_P', 'bmi' => 8.6)
)

Here's what I have tried and its not giving the output in the desired format:

Link to the demo: https://eval.in/142639

<?php
$data[] = array('ALT_ID' => '202143_N', 'bmi' => 2.5);
$data[] = array('ALT_ID' => '202144_P', 'bmi' => 1.2);
$data[] = array('ALT_ID' => '202145_N', 'bmi' => 6.6);
$data[] = array('ALT_ID' => '202146_P', 'bmi' => 3.6);
$data[] = array('ALT_ID' => '202147_N', 'bmi' => 7.6);
$data[] = array('ALT_ID' => '202148_P', 'bmi' => 8.6);

foreach ($data as $key => $row) {
    $volume[$key]  = $row['ALT_ID'];
    $bmi[$key] = $row['bmi'];
}

array_multisort($volume, SORT_ASC, SORT_STRING, $bmi, SORT_ASC, $data);

print_r($data);
?>

Thank you.


Solution

  • You need to prepend the last character of ALT_ID to your sort key.

    <?php
    
    $data[] = array('ALT_ID' => '202143_N', 'bmi' => 2.5);
    $data[] = array('ALT_ID' => '202144_P', 'bmi' => 1.2);
    $data[] = array('ALT_ID' => '202145_N', 'bmi' => 6.6);
    $data[] = array('ALT_ID' => '202146_P', 'bmi' => 3.6);
    $data[] = array('ALT_ID' => '202147_N', 'bmi' => 7.6);
    $data[] = array('ALT_ID' => '202148_P', 'bmi' => 8.6);
    
    foreach ($data as $key => $row) {
        $pieces = explode('_',$row['ALT_ID']);
        $id_piece = $pieces[1];
        $volume[$key]  = $id_piece . $row['ALT_ID'];
        $edition[$key] = $row['bmi'];
    }
    
    //edit
    array_multisort($volume, SORT_ASC, $edition, SORT_DESC, $data);
    
    print_r($data);
    
    ?>