如何在PHP中使用usort()在数组中按两个值排序,然后按ASC排序字段


How to sort by two values then a field by ASC in an array using usort() in PHP?

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

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

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

<?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);



 ?>

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

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)

目前输出为........

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 ........

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(),我仍然不能产生我想要的结果。什么解决方案可以用来产生结果?

好吧,我将给出一个带有两个标准的示例,但它没有在您的数据上进行测试。所以下面的compare()函数接收两个数组来比较。怎么做呢?在示例中,每个数组包含两个数字,首先对key = 0的数字进行排序,然后对key = 1的数字进行排序。当然,你的钥匙是不一样的。

function compare($array1,$array2)
{
  // numbers at key 0 are equal
  if ($array1[0] == $array2[0])
  {
    // so we look at key 1.
    if ($array1[1] == $array2[1]) return 0;
    return ($array1[1] < $array2[1]) ? -1 : 1;
  }
  return ($array1[0] < $array2[0]) ? -1 : 1;
}
$a = [[1,2],[3,4],[5,4],[4,2],[1,8]];
usort($a,'compare');
foreach ($a as $key => $value)
{
  echo "<pre>$key: ".print_r($value,TRUE)."'n</pre>";
}

你所需要做的就是使它适应你的情况。

这对数组中的两个值进行排序,正如您所说的,都是升序排序。如果你想让其中一个按降序排列,就把<改成>。这里使用的键是01,您的键是genderlast_name

有些值不能与<比较操作符进行比较,因此您需要使用其他操作符。在last_name的情况下,您可能希望使用strcasecmp()

代码中的主要问题:

  • 您按'r拆分:最好按'n拆分,它适用于所有平台。但是,由于换行符可以是'r'n,因此还需要删除另一个字符。这可以用trim()来做。所以我建议对所有值应用trim()
  • changeGender函数看起来很奇怪。你可以使用:return $gender === 'F' ? 'Female' : 'Male'
  • 你可能还想跳过输入中的空行。
  • 你在数组上循环排序,这是错误的。外环应该被移除。如果您需要它来列出数据,那么将排序移出它。

更正后的代码(也很好地缩进)后面是我标记为//**的注释:

$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上运行。其中使用您提供的样例数据。