如何在PHP中使用usort()按数组中的两个值对字段进行排序,然后对ASC进行排序? [英] How to sort by two values then a field by ASC in an array using usort() in PHP?

查看:92
本文介绍了如何在PHP中使用usort()按数组中的两个值对字段进行排序,然后对ASC进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经解析了三个不同的文本文件:

I have parsed three different text files:

space.txt

space.txt

Kournikova Anna F F 6-3-1975 Red
Hingis Martina M F 4-2-1979 Green
Seles Monica H F 12-2-197

comma.txt

comma.txt

Abercrombie, Neil, Male, Tan, 2/13/1943
Bishop, Timothy, Male, Yellow, 4/23/1967
Kelly, Sue, Female, Pink, 7/12/1959

pipe.txt

Smith | Steve | D | M | Red | 3-3-1985
Bonk | Radek | S | M | Green | 6-3-1975
Bouillon | Francis | G | M | Blue | 6-3-1975

我使用以下代码将所有文件解析为一个数组.............

I used the following code to parse all files into one array .............

<?php 

    $space_txt = './data/input/space.txt';
    $comma_txt = './data/input/comma.txt';
    $pipe_txt = './data/input/pipe.txt';

    $parsed_space_data = file_get_contents($space_txt);
    $parsed_comma_data = file_get_contents($comma_txt);
    $parsed_pipe_data = file_get_contents($pipe_txt);



    $space_array = myExpldeLoopFunc("space"," ", $parsed_space_data);
    $comma_array = myExpldeLoopFunc("comma",",", $parsed_comma_data);
    $pipe_array = myExpldeLoopFunc("pipe"," | ", $parsed_pipe_data);


    $finalArray = array_merge($space_array, $comma_array, $pipe_array);


    function changeGender($gender) {

        if($gender === 'F') {
            return str_replace('F', 'Female', $gender);
        }

        elseif($gender === 'M') {
            return str_replace('M', 'Male', $gender);
        }
    }

    function normalizeDate($date) {
        return str_replace('-', '/', $date);
    }









    function myExpldeLoopFunc($name, $sep, $data) {

        $parsedData = explode("\r", $data);




        $arr = [];
        foreach ($parsedData as $data) {
            $data_arr = explode($sep, $data);





            if($name == 'space'){

                $arr[] = [
                    "last_name" => $data_arr[0],
                    "first_name" => $data_arr[1],
                    // "middle_initial" => $data_arr[2],
                    "gender" => changeGender($data_arr[3]),
                    "date_of_birth" => normalizeDate($data_arr[4]),
                    "favorite_color" => $data_arr[5]



                ];








            }

                elseif($name == 'comma') {
                    $arr[] = [
                    "last_name" => $data_arr[0],
                    "first_name" => $data_arr[1],
                    "gender" => $data_arr[2],
                    "date_of_birth" => normalizeDate($data_arr[4]),
                    "favorite_color" => $data_arr[3]

                    ];
                }

            elseif ($name == 'pipe') {
                    $arr[] = [
                    "last_name" => $data_arr[0],
                    "first_name" => $data_arr[1],
                    // "middle_initial" => $data_arr[2],
                    "gender" => changeGender($data_arr[3]),
                    "date_of_birth" => normalizeDate($data_arr[5]),
                    "favorite_color" => $data_arr[4]



                ];


            }





    }



    return $arr;







        }








for ($i=0; $i < count($finalArray); $i++) {


foreach ($finalArray as $key => $row) {
$gender[$key] = $row['gender'];
$last_name[$key] = $row['last_name'];
}

array_multisort($gender, SORT_ASC, $last_name, SORT_ASC, $finalArray);

echo join(' ',  $finalArray[$i]) . '<br>';


    }

var_dump($finalArray);






 ?>

现在我有以下数组...........

Now I have the following array ...........

array (size=9)
  0 => 
    array (size=5)
      'last_name' => string 'Kournikova' (length=10)
      'first_name' => string 'Anna' (length=4)
      'gender' => string 'Female' (length=6)
      'date_of_birth' => string '6/3/1975' (length=8)
      'favorite_color' => string 'Red' (length=3)
  1 => 
    array (size=5)
      'last_name' => string '
Hingis' (length=7)
      'first_name' => string 'Martina' (length=7)
      'gender' => string 'Female' (length=6)
      'date_of_birth' => string '4/2/1979' (length=8)
      'favorite_color' => string 'Green' (length=5)
  2 => 
    array (size=5)
      'last_name' => string '
Seles' (length=6)
      'first_name' => string 'Monica' (length=6)
      'gender' => string 'Female' (length=6)
      'date_of_birth' => string '12/2/1973' (length=9)
      'favorite_color' => string 'Black' (length=5)
  3 => 
    array (size=5)
      'last_name' => string 'Abercrombie' (length=11)
      'first_name' => string ' Neil' (length=5)
      'gender' => string ' Male' (length=5)
      'date_of_birth' => string ' 2/13/1943' (length=10)
      'favorite_color' => string ' Tan' (length=4)
  4 => 
    array (size=5)
      'last_name' => string '
Bishop' (length=7)
      'first_name' => string ' Timothy' (length=8)
      'gender' => string ' Male' (length=5)
      'date_of_birth' => string ' 4/23/1967' (length=10)
      'favorite_color' => string ' Yellow' (length=7)
  5 => 
    array (size=5)
      'last_name' => string '
Kelly' (length=6)
      'first_name' => string ' Sue' (length=4)
      'gender' => string ' Female' (length=7)
      'date_of_birth' => string ' 7/12/1959' (length=10)
      'favorite_color' => string ' Pink' (length=5)
  6 => 
    array (size=5)
      'last_name' => string 'Smith' (length=5)
      'first_name' => string 'Steve' (length=5)
      'gender' => string 'Male' (length=4)
      'date_of_birth' => string '3/3/1985' (length=8)
      'favorite_color' => string 'Red' (length=3)
  7 => 
    array (size=5)
      'last_name' => string '
Bonk' (length=5)
      'first_name' => string 'Radek' (length=5)
      'gender' => string 'Male' (length=4)
      'date_of_birth' => string '6/3/1975' (length=8)
      'favorite_color' => string 'Green' (length=5)
  8 => 
    array (size=5)
      'last_name' => string '
Bouillon' (length=9)
      'first_name' => string 'Francis' (length=7)
      'gender' => string 'Male' (length=4)
      'date_of_birth' => string '6/3/1975' (length=8)
      'favorite_color' => string '

Blue' (length=4)

到目前为止,输出为........

So Far the output is ........

Kelly Sue Female 7/12/1959 Pink
Bishop Timothy Male 4/23/1967 Yellow
Abercrombie Neil Male 2/13/1943 Tan
Hingis Martina Female 4/2/1979 Green
Seles Monica Female 12/2/1973 Black
Kournikova Anna Female 6/3/1975 Red
Bonk Radek Male 6/3/1975 Green
Bouillon Francis Male 6/3/1975 Blue
Smith Steve Male 3/3/1985 Red

我想按女性",男性",然后按"last_name asc ........

I want to sort the array by Females then Males, then by last_name asc ........

Hingis Martina Female 4/2/1979 Green
Kelly Sue Female 7/12/1959 Pink
Kournikova Anna Female 6/3/1975 Red
Seles Monica Female 12/2/1973 Black
Abercrombie Neil Male 2/13/1943 Tan
Bishop Timothy Male 4/23/1967 Yellow
Bonk Radek Male 6/3/1975 Green
Bouillon Francis Male 6/3/1975 Blue
Smith Steve Male 3/3/1985 Red

我也尝试过……

function sortBy($field, &$array, $direction = 'asc') { 
usort($array, create_function('
$a, $b', ' $a = $a["' . $field . '"]; 
$b = $b["' . $field . '"]; 
if ($a == $b) { 
return 0; 
} 
return ($a ' . ($direction == 'desc' ? '>' : '<') .' $b) ? -1 : 1; ')); 
return true; 
} 

for ($i=0; $i < count($finalArray); $i++) { 
sortBy('gender', $finalArray); 
sortBy('last_name', $finalArray); 
echo join(' ', $finalArray[$i]) . '<br>'; 
}

我尝试了array_multisort(),usort(),sort(),asort(),但仍然无法产生想要的结果.可以使用什么解决方案来产生结果?

I have tried array_multisort(), usort(), sort(), asort(), and I still couldn't produce the results I wanted. What solution can be used to produce the outcome?

推荐答案

代码中的主要问题:

  • 您可以按\r进行拆分:最好按\n进行拆分,该版本在所有平台上均适用.但是,由于换行符可以为\r\n,因此您也需要删除该其他字符.您可以使用trim()执行此操作.因此,我建议将trim()应用于所有值.
  • changeGender函数看起来很奇怪.您可以使用return $gender === 'F' ? 'Female' : 'Male'.
  • 来完成所有操作.
  • 您可能还想跳过输入中的空行.
  • 您在数组中循环执行排序,这是错误的.该外部循环应被删除.如果您需要它来列出数据,则将其从列表中移出.
  • You split by \r: it is better to split by \n which works on all platforms. But since a line-feed can be \r\n, you need to remove that other character as well. This you can do with trim(). So I would suggest to apply trim() to all values.
  • The changeGender function looks weird. You can do all that with: return $gender === 'F' ? 'Female' : 'Male'.
  • You might also want to skip empty lines in your input.
  • You do your sorting in a loop on your array, that is wrong. That outer loop should be removed. If you need it for listing the data, then move the sorting out of it.

经过更正的代码(也很好地缩进了),其后我的注释标记为//**:

The corrected code (and also nicely indented) follows with my comments marked as //**:

$space_txt = './data/input/space.txt';
$comma_txt = './data/input/comma.txt';
$pipe_txt = './data/input/pipe.txt';

$parsed_space_data = file_get_contents($space_txt);
$parsed_comma_data = file_get_contents($comma_txt);
$parsed_pipe_data = file_get_contents($pipe_txt);

$space_array = myExpldeLoopFunc("space", " ", $parsed_space_data);
$comma_array = myExpldeLoopFunc("comma", ",", $parsed_comma_data);
$pipe_array = myExpldeLoopFunc("pipe", " | ", $parsed_pipe_data);

$finalArray = array_merge($space_array, $comma_array, $pipe_array);

function changeGender($gender) {
    return $gender === 'F' ? 'Female' : 'Male'; //** This is more straightforward
}

function normalizeDate($date) {
    return str_replace('-', '/', $date);
}

function myExpldeLoopFunc($name, $sep, $data) {
    $parsedData = explode("\n", $data); //** use "\n" instead of "\r"
    $arr = [];
    foreach ($parsedData as $data) {
        if ($data === "") continue; //** skip empty lines
        $data_arr = explode($sep, $data);
        if($name == 'space'){
            $arr[] = [
                "last_name" => trim($data_arr[0]), //** trim all elements (also removes "\r")
                "first_name" => trim($data_arr[1]),
                // "middle_initial" => trim($data_arr[2]),
                "gender" => changeGender(trim($data_arr[3])),
                "date_of_birth" => normalizeDate(trim($data_arr[4])),
                "favorite_color" => trim($data_arr[5])
            ];
        } elseif($name == 'comma') {
            $arr[] = [
                "last_name" => trim($data_arr[0]),
                "first_name" => trim($data_arr[1]),
                "gender" => trim($data_arr[2]),
                "date_of_birth" => normalizeDate(trim($data_arr[4])),
                "favorite_color" => trim($data_arr[3])
            ];
        } elseif ($name == 'pipe') {
            $arr[] = [
                "last_name" => trim($data_arr[0]),
                "first_name" => trim($data_arr[1]),
                // "middle_initial" => trim($data_arr[2]),
                "gender" => changeGender(trim($data_arr[3])),
                "date_of_birth" => normalizeDate(trim($data_arr[5])),
                "favorite_color" => trim($data_arr[4])
            ];
        }
    }
    return $arr;
}

//** Removed the bad for-loop that appeared here.
foreach ($finalArray as $key => $row) {
    $gender[$key] = $row['gender'];
    $last_name[$key] = $row['last_name'];
}
array_multisort($gender, SORT_ASC, $last_name, SORT_ASC, $finalArray);

//** Output in a loop, but leave the above sorting out of it 
foreach ($finalArray as $row) {
    echo join(' ',  $row) . "<br>\n";
}

print_r($finalArray);

查看它运行在使用您提供的示例数据的 eval.in 上.

See it run on eval.in which uses the sample data you provided.

顺序是所需的.

这篇关于如何在PHP中使用usort()按数组中的两个值对字段进行排序,然后对ASC进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆