0

如何按“总数”对数组进行排序?我试过arsort($myArray["total"]);但它返回null;

array (size=3)
  0 => 
    array (size=2)
      'name' => string 'Rnukir' (length=6)
      'total' => string '9m' (length=2)
  1 => 
    array (size=2)
      'name' => string 'Arnesista' (length=9)
      'total' => string '1m 45s' (length=6)
  2 => 
    array (size=2)
      'name' => string 'Omas' (length=8)
      'total' => string '1m 22s' (length=6)
4

4 回答 4

4

您需要使用其中一种usort变体并提供定义元素顺序的回调。

回调将传递当前比较的两个元素。在您的情况下,这是一个大小为 2 的数组(包含键名和总数)。它必须返回负数、0 或正值来指示第一个参数是否应该排在第二个参数之前、等于还是应该排在第二个参数之后。

一种可能性可能是strlen($a['total']) - strlen($b['total'])(因为我不知道您希望 PHP 如何神奇地对您的总计值进行排序)。

于 2013-09-18T06:17:52.780 回答
3

您正在寻找usort

usort($myArray, "compare");

如果您想对其进行精确排序,您的回调函数可能如下所示:

function compare($a, $b)
{
    // Get minutes and second from 'total' string
    $regular_expression = "/^(([0-9]{1,2})m )?([0-9]{1,2})s$/";
    if(preg_match($regular_expression, $a['total'], $matchA) != 1) return 0; // Invalid time string
    if(preg_match($regular_expression, $b['total'], $matchB) != 1) return 0; // Error handling

    // Calculate total amount of seconds
    $secondsA = 0;
    if(strlen($matchA[2]) > 0) $secondsA = 60 * (int)$matchA[2]; // Minutes
    if(strlen($matchA[2]) > 0) $secondsB = 60 * (int)$matchB[2];

    $secondsA += (int)$matchA[3]; // Seconds
    $secondsB += (int)$matchB[3]; 

    // Compare
    // Equal -> 0
    if ($secondsA == $secondsB) {
        return 0;
    }
    // A smaller than B -> -1
    // A higher than B -> 1
    return ($secondsA < $secondsB) ? -1 : 1;
}

PHP 知道使用“比较”函数并自动调用它与您的数组项。您不需要自己调用比较函数。(代码未经测试)

于 2013-09-18T06:54:21.273 回答
0
<?php
$array = array(
  0 =>array(
      'name' => 'Rnukir',
      'total' => '9m'),
  1 => array(
      'name' => 'Arnesista',
      'total' => '1m 45s'),
  2 => array(
      'name' => 'Omas',
      'total' => '1m 42s'),
  3 => array(
      'name' => 'John',
      'total' => '11m')
);

//1 - String value convert to time in second

$modified_array = array();
foreach($array as $key=>$each) {
    $each["total"] = stringToTime($each["total"]);
    $modified_array[$key] = $each;
}

//2 - Sort array based on second

usort($modified_array, "cmp");

//3 - Convert second to string

$final_array = array();
foreach($modified_array as $key=>$each) {
    $each["total"] = timeToString($each["total"]);
    $final_array[$key] = $each;
}

//4 - See output

print_r($final_array);


function stringToTime($str)
{
    $str_array = explode(" ",$str);
    $v = 0;
    foreach($str_array as $key=>$value) {
        $v  += substr($value,-1)=='m' ? substr($value,0,-1)*60 : substr($value,0,-1)*1;

    }
    return $v;
}

function timeToString($time)
{
    $m = intval($time/60);
    $s = $time%60;
    if(empty($s))
        return $m."m";
    else
        return $m."m ".$s."s";
}

function cmp($a, $b)
{
    if ($a['total'] == $b['total']) {
        return 0;
    }
    return ($a['total'] > $b['total']) ? -1 : 1;
}
?>
于 2013-09-18T07:36:46.090 回答
0

尝试这样的事情

<?php

  $array = array(
  0 =>array(
      'name' => 'Rnukir',
      'total' => '1'),
  1 => array(
      'name' => 'Arnesista',
      'total' => '2'),
  2 => array(
      'name' => 'Omas',
      'total' => '3'),
  3 => array(
      'name' => 'John',
      'total' => '4')
);

foreach ($array as $key => $row) {
    $name[$key]  = $row['name'];
    $total[$key] = $row['total'];
}
 print_r($total);


 array_multisort($total, SORT_DESC, $array);
//  array_multisort($total, SORT_DESC, $name, SORT_ASC $array);
echo "<pre>";
  print_r($array);
echo "</pre>";
?> 
于 2013-09-18T08:25:13.600 回答