简体   繁体   中英

Sort a multi-dimensional Array in PHP

i do not unstand the way to sort a multi-dimensional array in php. I have a structure like this:

Array (
   [0] (
      ['vname'] => "Bernt"
      ['nname'] => "Mayer"
      ['kl_name'] => "ZR4"
   )
   [1] (
      ['vname'] => "Albert"
      ['nname'] => "Mayer"
      ['kl_name'] => "TR4"
   )
)

My goal is now to first sort by kl_name, and then by nname and then vname. Most important is kl_name. First i tought i should make objects and store them in the array, but i think sorting them is even more complex. php.net has a nice article about array_multisort, but year, i dont understand it :/

You'll want to sort the array with a user defined function (with usort ).

You can then manually specify how you'd like the items to be ordered using the kl_name , nname and vname attributes.

Something like this:

usort($arr, function($a, $b) {
    if ($a['kl_name'] !== $b['kl_name']) {
        return strcmp($a['kl_name'], $b['kl_name']);
    } else if ($a['nname'] !== $b['nname']) {
        return strcmp($a['nname'], $b['nname']);
    } else {
        return strcmp($a['vname'], $b['vname']);
    }
});

The function will first attempt to sort by kl_name , then by nname and finally by vname if all previous values are equal.

You can use array_multisort for this.

// Obtain a list of columns
foreach ($data as $key => $row) {
    $kl_name[$key] = $row['kl_name'];
    $nname[$key]   = $row['nname'];
    $vname[$key]   = $row['vname'];
}

// Sort
array_multisort($kl_name, SORT_ASC, $nname, SORT_ASC, $vname, SORT_ASC, $data);

See http://php.net/array_multisort for more details.

I've never understood array_multisort either. I just use usort for things like this. What you do is, you compare the 1st field, and if it's the same, then you compare the 2nd... and so on.

So, it would look something like this (assuming $data is your array).

usort($data, function($a, $b){
    $sort_kl_name = strnatcasecmp($a['kl_name'], $b['kl_name']);
    if($sort_kl_name === 0){
        $sort_nname = strnatcasecmp($a['nname'], $b['nname']);
        if($sort_kl_name === 0){
            return strnatcasecmp($a['vname'], $b['vname']);
        }
        return $sort_nname;
    }
    return $sort_kl_name;
});

This looks a little messy, with lots of if s. Let's simplify that with a foreach .

$sortLevels = array('kl_name', 'nname', 'vname');

usort($data, function($a, $b) use($sortLevels){
    foreach($sortLevels as $field){
        $sort = strnatcasecmp($a[$field], $a[$field]);
        if($sort !== 0){
            break;
        }
    }
    return $sort;
});

DEMO: https://eval.in/173774

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM