如何在PHP中使用usort()按数组中的两个值对字段进行排序,然后对ASC进行排序? [英] How to sort by two values then a field by ASC in an array using usort() in PHP?
问题描述
我已经解析了三个不同的文本文件:
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 withtrim()
. So I would suggest to applytrim()
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屋!