2013-07-22 23 views
0

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

什么是'$ video_categories [belt_id]''中的'belt_id'?不是颜色ID吗?所以你可以按这个排序.. – bitWorking

+0

不,这是一个更大的系统的一部分。皮带ID来自数据库,并且是相当随意的。这个系统是为了排序,如果已经有一些排序正确的话就不会成为问题;) –

回答

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]; 
}); 
+0

是的,在SO上很难为你们“剪出一块”。我认为一旦你分解它,这将是非常基本的。我想这是正确的。阵列翻转工作正常!我知道答案会出现在颜色的数组键中,但我无法把它放在手指上。谢谢 –

+0

不客气。 –

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 
) 
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" 
} 
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 

这应该这样做。