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。(仅供参考,颜色与单词不匹配,它们被移动到不同的数组 - 所以我不需要在这里进行错误检查)。

// 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' );
4

4 回答 4

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];
});
于 2013-07-22T23:21:11.473 回答
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
)
于 2013-07-22T23:32:00.657 回答
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"
}
于 2013-07-22T23:35:36.857 回答
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

这应该这样做。

于 2013-07-22T23:58:12.467 回答