【问题标题】:Sorting arrays by date按日期排序数组
【发布时间】:2012-02-08 23:17:44
【问题描述】:

我有一个问题。我正在通过从 mysql 获取数据并将三个查询结果合并到一个数组中来构建一个数组。

我像这样将数据放入数组中:

while ($a = mysql_fetch_object($activities)) {
            $a->type = 1;
            $array1[] = $a;
        }
        while ($k = mysql_fetch_object($fuups)) {
        $k->type = 2;
            $array1[] = $k;
        }
        while ($x = mysql_fetch_object($refuups)) {
            $x->type = 3;
            $array1[] = $x;
        }

        return (object)$array1;

这会返回如下内容:

stdClass Object
(
    [0] => stdClass Object
        (
            [added] => 2012-01-17 07:33:53
            [type] => 1
        )

    [1] => stdClass Object
        (
            [added] => 2012-01-13 06:36:22
            [type] => 1
        )

    [2] => stdClass Object
        (
            [added_type_2] => 2012-01-09 04:01:12
            [type] => 2
        )

    [3] => stdClass Object
        (
            [added_type_2] => 2012-02-08 02:08:32
            [type] => 2
        )

    [4] => stdClass Object
        (
            [added_type_2] => 2012-01-25 00:09:08
            [type] => 2
        )

    [5] => stdClass Object
        (
            [added_type_3] => 2012-01-23 00:09:08
            [type] => 3
        )

    [6] => stdClass Object
        (
            [added_type_3] => 2012-01-22 00:09:08
            [type] => 3
        )

)

我尝试了诸如 asort、ksort、sort 之类的方法,但没有运气。还可以通过“按添加的 desc 排序”获取日期,谢谢

【问题讨论】:

  • 想想你能不能调用这三个查询并创建联合并得到一个结果.. 易于在 sql 中排序..?
  • 我也试过了,但我不知道 php 如何知道查询得到的内容类型是什么
  • 对这种排序不太确定,但是您可以使用查询对其进行排序并以所需的顺序从数据库中获取它吗?
  • 您是否尝试过选择“TO_UNIXTIME([date field]) AS timestamp”并将数组存储为“$array[$a->timestamp]”?然后你就有了一个易于排序的数字键控数组,并且需要更少的 PHP 来处理。

标签: php mysql arrays


【解决方案1】:

您要做的是对多维数组进行排序,您可以在 Google 上找到很多关于此的内容。一个不错的优雅解决方案是这样的:

// Sort the multidimensional array
usort($results, "custom_sort");

// Define the custom sort function
function custom_sort($a,$b) {
     return $a['some_sub_var']>$b['some_sub_var'];
}

编辑 1:

对于那些怀疑此代码是否有效的 cmets,请随意尝试(我什至添加了一个重复的日期以用于测试目的):

function custom_sort($a,$b) {
        return $a['added']>$b['added'];
}

$arrayToSort = array(
                    array(
                        "added" => "2012-01-17 07:33:53",
                        "type" => "1"
                    ),
                    array(
                        "added" => "2012-01-13 06:36:22",
                        "type" => "1"
                    ),
                    array(
                        "added" => "2012-01-09 04:01:12",
                        "type" => "2"
                    ),
                    array(
                        "added" => "2012-02-08 02:08:32",
                        "type" => "2"
                    ),
                    array(
                        "added" => "2012-01-25 00:09:08",
                        "type" => "2"
                    ),
                    array(
                        "added" => "2012-01-13 06:36:22",
                        "type" => "1"
                    ),
                    array(
                        "added" => "2012-01-13 06:36:22",
                        "type" => "1"
                    ),
                    array(
                        "added" => "2012-01-23 00:09:08",
                        "type" => "3"
                    ),
                    array(
                        "added" => "2012-01-22 00:09:08",
                        "type" => "3"
                    )
                );
usort($arrayToSort, "custom_sort");

echo '<pre>';
print_r($arrayToSort);
echo '</pre>';

一个快速测试的好地方是去http://writecodeonline.com/php/

【讨论】:

  • @Garry Welding:如果$a 小于$b,您的代码将返回0(实际上是null)而不是-10 如果相等,则应该返回。您需要阅读文档。
  • 我会鼓励上面的两位评论者实际尝试代码。
  • @Garry Welding:我试过了,你是对的。无论是否返回-1,它都会对其进行排序。好奇,我去看了源代码,结果发现 Zend 并不关心返回什么数字,只关心它是否大于零:来自zend_qsort.ccompare(begin, seg1 TSRMLS_CC) &gt; 0。因此,尽管有文档(除非它们的快速排序实现在不久的将来发生更改,这是非常值得怀疑的),但 -10 的返回值似乎被视为完全相同。 + 1
【解决方案2】:

如果将 fetch 对象更改为 fetch assoc,则可以使用 usort():

function my_date_sort($a,$b) {
   if(isset($a[0]) && isset($b[0])) {
       $a = strtotime($a[0]); // optionally convert to time
       $b = strtotime($b[0]);
       if($a == $b) return 0; 
       else return ($a > $b) ? 1 : -1;
   } else { // no valid subs, change this to put empty ones on top or bottom
       return 1; // put at bottom, -1 would put at top. 
}


usort($results, 'my_date_sort');

祝你好运……

【讨论】:

  • +1 仅供参考,直接字符串比较在他的特定情况下可以工作,不需要 strtotime:if ('2012-01-17 07:33:53' &gt; '2012-01-13 06:36:22') 实际上可以正常工作。
【解决方案3】:

在选择而不是尝试自行对数组进行排序时,您可能应该使用UNION。无论如何,如果你不得不像这样使用usort

function cmp( $a, $b){
  if( !($a instanceOf stdClass) && !($b instanceOf stdClass)){
    return 0;
  }

  // Check object
  if(  !($a instanceOf stdClass)){
    return -1;
  }
  if(  !($b instanceOf stdClass)){
    return 1;
  }

  $aVal = NULL;
  if( isset( $a->added)){
    $aVal = $a->added;
  } elseif( isset( $a->added_type_2)){
    $aVal = $a->added_type_2;
  } ...

  // The same for b
  if( ($aVal == NULL) && ($bVal == NULL)){
    return 0;
  }

  if( $aVal == NULL){
    return -1;
  }

  if( $bVal == NULL){
    return 1;
  }

  if( $aVal == $bVal){
    return 0;
  }

  return ($aVal > $bVal) ? 1 : -1;

}

usort( $array, 'cmp');

正如您所见,当确保对象具有正确的类型和正确的值时,如何比较对象可能会变得复杂。选择 mysql 列时,您应该至少使用 SELECT added_type_2 AS added 以使列名更紧凑,条件更简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-19
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多