TL; DR:我需要对一系列特定单词进行排序。订单应与现有数组匹配。请参阅最后一个代码块中的示例代码。
我有一系列标题,每个标题的第一个单词是一种颜色。我此时习惯于对数组进行排序,但这一点令人困惑。
问题:我需要根据已排序的单词列表手动对单词数组进行排序。我已设置uasort
,以便我准备好以下两个变量进行比较:
// first comparison:
$a_first = strtolower( $a_split[0] ); // white
$b_first = strtolower( $b_split[0] ); // blue
// 2nd comparison:
$a_first = strtolower( $a_split[0] ); // purple
$b_first = strtolower( $b_split[0] ); // white
// 3rd comparison:
$a_first = strtolower( $a_split[0] ); // blue
$b_first = strtolower( $b_split[0] ); // purple
我需要通过皮带排名对这些颜色进行排序,以获得柔术排名系统。这是正确顺序的数组:
$color_order = explode(' ', 'white blue purple brown black black-red coral white-red red');
/* $color_order =
Array (
[0] => white
[1] => blue
[2] => purple
[3] => brown
[4] => black
[5] => black-red
[6] => coral
[7] => white-red
[8] => red
)
Current (incorrect) results:
1. Blue
2. Purple
3. White
Desired results:
1. White
2. Blue
3. Purple
*/
我当前的代码,来自uasort(),使用strcmp按字母顺序排序。我需要用可以使用我的颜色数组排序的东西替换strcmp。 (Fyi,颜色与单词不匹配,它们被移动到不同的数组 - 所以我不需要在这里进行错误检查)。
// Sort Step 1: Sort belt level by color
// $video_categories[belt_id][term]->name = "White belt example"
function _sort_belt_names( $a, $b ) {
$a_name = trim( $a['term']->name );
$b_name = trim( $b['term']->name );
$a_split = explode( ' ', $a_name );
$b_split = explode( ' ', $b_name );
if ( $a_split && $b_split ) {
$color_order = explode(' ', 'white blue purple brown black black-red coral white-red red');
// IMPORTANT STUFF BELOW! ----
$a_first = strtolower( $a_split[0] ); // purple
$b_first = strtolower( $b_split[0] ); // white
// Compare $a_first $b_first against $color_order
// White should come first, red should come last
// Return -1 (early), 0 (equal), or 1 (later)
// IMPORTANT STUFF ABOVE! ----
}
// If explode fails, sort original names alphabetically.
return strcmp( $a_name, $b_name );
}
// ---
uasort( $video_categories, '_sort_belt_names' );
答案 0 :(得分:1)
没有看到数组的例子,它很难编码,但这样的事情应该有效:
usort($arr, function ($a, $b){
$ord =array_flip(array ('white', 'blue', 'purple', 'brown', 'black', 'black-red', 'coral', 'white-red', 'red'));
return $ord[$b] - $ord[$a];
});
答案 1 :(得分:1)
这是一个使用预定义订单列表的自定义比较功能。
function cmp($a,$b) {
$order = array_flip(
array(
'white',
'blue',
'purple',
'brown',
'black',
'black-red',
'coral',
'white-red',
'red',
)
);
$a = strtolower($a);
$b = strtolower($b);
if(!isset($order[$a])) {
if(!isset($order[$b])) {
return strcmp($a,$b);
}
return 1;
}
if(!isset($order[$b])) {
return -1;
}
return $order[$a] - $order[$b];
}
列表中存在的任何2个单词都会根据其顺序进行复制。 如果列表中存在1个字而另一个字不存在,则后者为“较低”字。 如果两者都不存在于列表中,则它们就像任何其他字符串一样被复制。
将此功能与usort
一起使用,如下所示:
$colors = array(
'blue',
'purple',
'white',
'foo',
'bar',
);
usort($colors,'cmp');
print_r($colors);
你会得到:
Array
(
[0] => white
[1] => blue
[2] => purple
[3] => bar
[4] => foo
)
答案 2 :(得分:1)
<?php
function _sort_belt_names( $a, $b ) {
$a_split = explode( ' ', $a );
$b_split = explode( ' ', $b );
if ( $a_split && $b_split ) {
$color_order = explode(' ', 'white blue purple brown black black-red coral white-red red');
// IMPORTANT STUFF BELOW! ----
// Convert all the elements in $a_split and $b_split to lowercase
foreach ( $color_order as $key => $value) {
if ( in_array($value , $a_split) || in_array($value, $b_split)) {
$sorted[] = $value;
}
}
var_dump($sorted);
// IMPORTANT STUFF ABOVE! ----
}
// If explode fails, sort original names alphabetically.
// Do whatever you whant to do if explode fails
}
$a = "black white coral blue";
$b = "black-red purple";
_sort_belt_names($a, $b);
?>
$ php sorting.php
array(6) {
[0]=>
string(5) "white"
[1]=>
string(4) "blue"
[2]=>
string(6) "purple"
[3]=>
string(5) "black"
[4]=>
string(9) "black-red"
[5]=>
string(5) "coral"
}
答案 3 :(得分:1)
不确定uasort是否是正确的选择。如何检查输入数组与颜色数组(翻转)并通过将它们添加到键入翻转值(以前的数字键)的数组来排序:
// Sort Step 1: setup color sort array(s)
$color_order = explode(' ', strtolower('white blue purple brown black black-red coral white-red red'));
$color_keyed = array_flip($color_order);
// Sort Step 2: Sort belt level by color
// $video_categories[belt_id][term]->name = "White belt example"
$unmatched=array();
$categorised=array();
$catsorted=array();
foreach($video_categories as $a) {
$a_names = explode(' ',strtolower(trim( $a['term']->name)));
$a_name=$a_names[0];
// check if $a_name is a value in $color_order or a key in $color_keyed
if (!array_key_exists("$a_name",$color_keyed) {
$unmatched[]=$a;
} else {
// separated these 2 commands to make more readable but could have done:
// $categorised[$color_keyed["$a_name"]][]=$a;
// Putting the video_categories item into an array ordered by the key value of the matching color.
$catkey=$color_keyed["$a_name"];
$categorised[$catkey][]=$a;
}
}
// You can now run a double foreach over the 2 dimensional $categorised array
// to pick out the ordered video_categories entries:
// then write them to a single dimensional array
foreach ($categorised as $colkey=>$catkeyed)
{
foreach ($catkeyed as $cat) {
$catsorted[]=$cat;
}
// ---
// $catsorted should now be a flat array
// containing the original $video_categories array entries
// sorted by the order of the grade colors above
这应该这样做。