douou1872 2016-06-26 09:29
浏览 68
已采纳

如何使用PHP中的usort()在数组中按ASC对两个值进行排序?

I have parsed three different text files:

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

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("", $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

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

I also tried ......

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>'; 
}

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?

  • 写回答

2条回答 默认 最新

  • dongtuan5367 2016-06-26 11:31
    关注

    The main issues in your code:

    • You split by : it is better to split by which works on all platforms. But since a line-feed can be , 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("
    ", $data); //** use "
    " instead of ""
        $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 "")
                    "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>
    ";
    }
    
    print_r($finalArray);
    

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

    The order is as desired.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题