【问题标题】:Alphanumerical array sorting (CAVEAT: spaces as a thousands separator in numbers)字母数字数组排序(CAVEAT:空格作为数字中的千位分隔符)
【发布时间】:2012-09-28 13:35:30
【问题描述】:

怎么做。例如我们有一个数组:

array(
    0 => 'Regular 1 000',
    1 => 'Regular 500',
    2 => 'Regular 2 000',
    3 => 'Big',
    4 => 'Regular 1 000 000',
    5 => 'Regular 50 000'
)

我需要按以下顺序放置它们:

array(
    3 => 'Big',
    1 => 'Regular 500',
    0 => 'Regular 1 000',
    2 => 'Regular 2 000',
    5 => 'Regular 50 000',
    4 => 'Regular 1 000 000'
 )

而且我需要维护索引关联。看来我需要使用uasort。谁能向我建议一个用于 callable ( $cmp_function ) 值的函数?

【问题讨论】:

  • 刮出数字并仅对它们进行排序。
  • 这比应该做的要难,但是完成了~

标签: php sorting


【解决方案1】:

这仅适用于您的数组的数字部分,但我仍在尝试围绕字母排序的杂耍数组。如果有人可以添加,请随时更新。
如果可能,您可能想尝试更改格式,因为这是一个头痛

$x = array(
    'Regular 1 000',
    'Regular 500',
    'Regular 2 000',
    'Big',
    'Regular 1 000 000',
    'Regular 50 000'
);

给予:

编辑:尤里卡!

$x = array(
    'A 100', // extra for testing
    'Regular 1 000',
    'Regular 500',
    'Regular 2 000',
    'Big',
    'Regular 1 000 000',
    'Regular 50 000'
);

function cus_sort($a, $b) { // you can also just do $x = function ($a, $b) {}
    $tmp_a = array(); $tmp_b = array(); // temp storage
    $tmp_a = explode(" ", $a, 2);
    if (@$tmp_a[1]) { // tmp_a exists (suppress invalid offset error if not)
        $a_numeric = (int)preg_replace("/[^0-9]/", '', $tmp_a[1]);
        // remove all non-numerical (...should add hyphens if needed...)
    } else {
        $a_numeric = false; // text only.
    }
    // else make sure that it evaluates false when we check.
    $tmp_b = explode(" ", $b, 2); // split into maximum 2 parts at first space.
    if (@$tmp_b[1]) { // tmp_b exists (suppress invalid offset error if not)
        $b_numeric = (int)preg_replace("/[^0-9]/", '', $tmp_b[1]);
    } else {
        $b_numeric = false; 
    }
    // onwards to sorting
    if ($tmp_a[0] == $tmp_b[0]) { //alphabetical parts are the same.
    // numerical sort
        if (($a_numeric > $b_numeric) || (!$b_numeric)) {
            return 1;
        } elseif (($a_numeric < $b_numeric) || (!$a_numeric)) {
            return -1;
        } else {
            return 0;
        }
    } else {
        // alpha sort
        $compare = strcasecmp($tmp_a[0], $tmp_b[0]);
        // see note below
        if ($compare > 0) {
            return 1;
        } elseif ($compare < 0) {
            return -1;
        } else {
            return 0;
        }
    }
}

uasort($x, "cus_sort");

注意:strcasecmp(string $a, string $b) 是一个 case insensitive 数字方式来检查是否按顺序。

print_r 返回:

Array
(
    [0] => A 100
    [4] => Big
    [2] => Regular 500
    [1] => Regular 1 000
    [3] => Regular 2 000
    [6] => Regular 50 000
    [5] => Regular 1 000 000
)

【讨论】:

  • 有效,但仅适用于您所说的数字。不能对空格做任何事情,因为需要保持它们完整。
  • 尝试将第一个空格处的数组拆分为两个值,并通过 ID 引用它们。 (例如"str" . $key
【解决方案2】:

试试这个代码

$sorted_arr = array_map(
  function ($str) {
    preg_match('/[a-zA-Z]*\s*((\d+\s*)*)/', $str, $matches);
    return (int) str_replace(' ', '', $matches[1]);
  }, $arr
);
asort($sorted_arr, SORT_NUMERIC);
foreach ($sorted_arr as $key=>$value)
  $sorted_arr[$key] = $arr[$key];
print_r($sorted_arr);

【讨论】:

  • 它运行良好,但除此之外仍然没有解决 OP 想要的字母排序。我正在白板上写字,试图解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
  • 2018-06-22
相关资源
最近更新 更多