排序å,ä,ö - 与a / o混合

时间:2013-04-29 19:50:44

标签: php wordpress sorting tags character

使用WordPress和PHP,我正在按照第一个字符排序的网站上创建标签列表,

<?php
$letters = range( 'a','z' );
array_push( $letters, 'å', 'ä', 'ö' );
foreach ( $letters as $index=>$letter ) : ?>
<h3><?php echo $letter; ?></h3>
<ul>
<?php
$tags = get_tags( array('name__like' => $letter, 'hide_empty' => 0) );
foreach ( $tags as $tag ) :
?>
<li><a href="/tag/<?php echo $tag->slug; ?>/"><?php echo $tag->name; ?></a></li>
<?php endforeach; ?>
</ul>
<?php endforeach; ?>

输出工作除了我的瑞典字符å,ä,ö也包含在/ o中,反之亦然,好像PHP无法区分它们(即使手动将它们作为自己的条目推入阵列)。想法?

1 个答案:

答案 0 :(得分:0)

我一直在和同样的问题作斗争。您可以将setlocale()asort($ array,SORT_LOCALE_STRING)一起使用。这将ÅÄÖ字符放在最后。不幸的是他们的顺序错了。 PHP对它们进行排序ä,å,ö。在北欧语言中(至少在瑞典语字母表中),其分类如下:å,ä,ö。经过大量的谷歌搜索后,我无法用PHP原生功能解决这个问题,所以我做了自己的“修补”排序,我认为我可能会分享。

我绝不是编写针对计算速度优化的代码的专家,因此我确信可以对此代码进行一些改进。我欢迎你指出它们!

此函数根据整个字符串对数组进行排序,而不仅仅是第一个字符。但我相信这是最有用的方法,如果你想在第一个之后忽略所有字符我肯定你可以修改它。此外,修改它以应用于其他字符和其他排序顺序非常容易。享受

function sort_nordic(&$array) {
  uasort($array, 'nordic_cmp');
}
function nordic_cmp($a, $b) {
  // If å, ä, and ö is missing from first string, just use PHP's native function
  if (preg_match('/([å]|[ä]|[ö]|[Å]|[Ä]|[Ö])/', $a) == 0) {
    return strcoll($a, $b);
  }
  // If å, ä, and ö is missing from second string, also use PHP's native function
  if (preg_match('/([å]|[ä]|[ö]|[Å]|[Ä]|[Ö])/', $b) == 0) {
    return strcoll($a, $b);
  }

  // Arriving here both the strings contains some characters we have too look out for
  // First, create arrays from the strings so we can easily loop over the characters
  // Comparison is made in lowercase
  $a_arr = preg_split('//u', mb_strtolower($a), -1, PREG_SPLIT_NO_EMPTY);
  $b_arr = preg_split('//u', mb_strtolower($b), -1, PREG_SPLIT_NO_EMPTY);

  // Get the length of the shortest string
  $end = min(mb_strlen($a), mb_strlen($b));

  // Loop over the characters and compare them in pairs
  for ($i = 0; $i < $end; $i++) {
    // Check if character in the first string is one that we have to correct for
    if (mb_stripos("åäö", $a_arr[$i]) !== false) {
      // Computes the corrected return value. The first character "-" is just a 
      // nonsene placeholder to return 1 for "ä", 2 for "å" and 3 for "ö"
      $r = mb_stripos("-åäö", $a_arr[$i]) - mb_stripos("-åäö", $b_arr[$i]);
      if ($r != 0) {
        return $r;
      }
    } else {
      // If the character is not a character that we have to correct for 
      // the PHP native works fine
      $r = strcoll($a_arr[$i], $b_arr[$i]);
      if ($r != 0) {
        return $r;
      }
    }
  }
  // Fallback: If so far there has been no call to return() then the 
  // strings are idenical up until the length of the shorter string.
  // Then let the lengths of the strings determine the order
  return mb_strlen($a) - mb_strlen($b);
}