douxie5176 2015-10-08 13:03
浏览 71
已采纳

在两个条件下对数组进行排序

Ok, so I am having trouble coming up with a solution to my problem. Basically, what I am trying to accomplish is to total the number of registrations in the last twelve months, starting with the current month.

First, since I cannot guarantee that each month would have a return, I built an array and populated it with my query results. I was able to pull all the data that I needed, but I am having trouble "sorting" them as you will.

I want to be able to display it in this manner, ex:

It is currently october so the months would list like this:

Nov 2014, Dec 2014, Jan 2015, Feb 2015, March 2015, ... October 2015.

Using this array

$months = array(
            '1'=>array('TOTAL'=>0, 'YEAR'=>NULL), 
            '2'=>array('TOTAL'=>0, 'YEAR'=>NULL), 
            '3'=>array('TOTAL'=>0, 'YEAR'=>NULL), 
            '4'=>array('TOTAL'=>0, 'YEAR'=>NULL),  
            '5'=>array('TOTAL'=>0, 'YEAR'=>NULL),  
            '6'=>array('TOTAL'=>0, 'YEAR'=>NULL),  
            '7'=>array('TOTAL'=>0, 'YEAR'=>NULL),  
            '8'=>array('TOTAL'=>0, 'YEAR'=>NULL),  
            '9'=>array('TOTAL'=>0, 'YEAR'=>NULL),  
            '10'=>array('TOTAL'=>0, 'YEAR'=>NULL),  
            '11'=>array('TOTAL'=>0, 'YEAR'=>NULL),  
            '12'=>array('TOTAL'=>0, 'YEAR'=>NULL)
        );

And populating it with the results I get:

key: 1 (January) total: 17 year: 2015
key: 2 (February) total: 20 year: 2015
key: 3 (March) total: 23 year: 2015
key: 4 (April) total: 29 year: 2015
key: 5 (May) total: 26 year: 2015
key: 6 (June) total: 26 year: 2015
key: 7 (July) total: 26 year: 2015
key: 8 (August) total: 24 year: 2015
key: 9 (September) total: 22 year: 2015
key: 10 (October) total: 24 year: 2015
key: 11 (November) total: 30 year: 2014
key: 12 (December) total: 42 year: 2014

Here's the query/loop

    $query = "SELECT MONTH(DATE_ADDED) as MONTH_NUMBER, MONTHNAME(DATE_ADDED) as MONTH_NAME, COUNT(*) as TOTAL_REGISTRATIONS, YEAR(DATE_ADDED) AS YEAR FROM MEMBERS WHERE DATE_ADDED >= (CURDATE() - INTERVAL (DAY(CURDATE()) - 1) DAY) - INTERVAL 11 MONTH GROUP BY MONTH(DATE_ADDED) ORDER BY DATE_ADDED ASC";
    $result = mysql_query($query) or die(mysql_error());

while($row = mysql_fetch_assoc($result)){

    $months[$row['MONTH_NUMBER']]['NAME'] = $row['MONTH_NAME'];
    $months[$row['MONTH_NUMBER']]['TOTAL'] = $row['TOTAL_REGISTRATIONS'];
    $months[$row['MONTH_NUMBER']]['YEAR'] = $row['YEAR'];
    $months[$row['MONTH_NUMBER']]['MONTH_NUM'] = $row['MONTH_NUMBER'];

}

    foreach($months as $key=>$data){
        echo 'key: '.$key. ' ('.$data['NAME'].')   total:   '.$data['TOTAL'].'      year: '.$data['YEAR'].'<br/>';
    }
    exit;

Edit: So far, I've been able to accomplish this:

key: 12 (December) total: 42 year: 2014
key: 11 (November) total: 30 year: 2014
key: 10 (October) total: 24 year: 2015
key: 9 (September) total: 22 year: 2015
key: 8 (August) total: 24 year: 2015
key: 7 (July) total: 26 year: 2015
key: 6 (June) total: 26 year: 2015
key: 5 (May) total: 26 year: 2015
key: 4 (April) total: 29 year: 2015
key: 3 (March) total: 23 year: 2015
key: 2 (February) total: 20 year: 2015
key: 1 (January) total: 17 year: 2015

using this code:

function sortArray(array $a, array $b) {

    if($a['YEAR'] <= $b['YEAR'] && $a['MONTH_NUM'] < $b['MONTH_NUM']){
        return 1;
    }elseif($a['YEAR'] <= $b['YEAR'] && $a['MONTH_NUM'] > $b['MONTH_NUM']){
        return -1;
    }elseif($a['YEAR'] >= $b['YEAR'] && $a['MONTH_NUM'] > $b['MONTH_NUM']){
        return -1;
    }elseif($a['YEAR'] >= $b['YEAR'] && $a['MONTH_NUM'] < $b['MONTH_NUM']){
        return 1;
    } else {
        return 0;
    }

}
// Sort
uasort($months, 'sortArray');

Edit: You can see it sorts by the year properly, but lists the months the wrong way.

Edit: Desired Output

key: 11 (November) total: 00 year: 2014
key: 12 (December) total: 00 year: 2014
key: 1 (January) total: 00 year: 2015
key: 2 (February) total: 00 year: 2015
key: 3 (March) total: 00 year: 2015
key: 4 (April) total: 00 year: 2015
key: 5 (May) total: 00 year: 2015
key: 6 (June) total: 00 year: 2015
key: 7 (July) total: 00 year: 2015
key: 8 (August) total: 00 year: 2015
key: 9 (September) total: 00 year: 2015
key: 10 (October) total: 00 year: 2015

Ultimately, I will be displaying these in a bar graph showing the total per month over the last year.

I don't know if this is the best way to go about doing this, any suggestions are welcome.

  • 写回答

2条回答 默认 最新

  • dongyisa6254 2015-10-08 18:16
    关注

    I think your answer lies as an user contribution note on PHP Docs's uasort() function page, by "clement.hk". I've adapted it to your problem and it seems to work!

    <?php
    
    // array reproduction
    $months = array(
            '1'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '2'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '3'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '4'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '5'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '6'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '7'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '8'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '9'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '10'=>array('TOTAL'=>0, 'YEAR'=>2015),
            '11'=>array('TOTAL'=>0, 'YEAR'=>2014),
            '12'=>array('TOTAL'=>0, 'YEAR'=>2014)
    );
    
    // "clement.hk"'s alternate version of "uasort", where it keeps
    // the index order when $a == $b. Credits to him!
    function stable_uasort(&$array, $cmp_function) {
        if(count($array) < 2) {
            return;
        }
        $halfway = count($array) / 2;
        $array1 = array_slice($array, 0, $halfway, TRUE);
        $array2 = array_slice($array, $halfway, NULL, TRUE);
    
        stable_uasort($array1, $cmp_function);
        stable_uasort($array2, $cmp_function);
        if(call_user_func($cmp_function, end($array1), reset($array2)) < 1) {
            $array = $array1 + $array2;
            return;
        }
        $array = array();
        reset($array1);
        reset($array2);
        while(current($array1) && current($array2)) {
            if(call_user_func($cmp_function, current($array1), current($array2)) < 1) {
                $array[key($array1)] = current($array1);
                next($array1);
            } else {
                $array[key($array2)] = current($array2);
                next($array2);
            }
        }
        while(current($array1)) {
            $array[key($array1)] = current($array1);
            next($array1);
        }
        while(current($array2)) {
            $array[key($array2)] = current($array2);
            next($array2);
        }
        return;
    }
    
    // the equal comparison is pointless since you have twelve months of the same
    // year... we need comparison only when it differs
    stable_uasort($months, function ($a, $b) {
    /*     if($a['YEAR'] == $b['YEAR']) {
            return 0;
        } */
        return ($a['YEAR'] > $b['YEAR']) ? 1 : -1;
    });
    
    
    echo '<pre>';
    print_r($months);
    

    The output:

    Array
    (
        [11] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2014
            )
    
        [12] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2014
            )
    
        [1] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
        [2] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
        [3] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
        [4] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
        [5] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
        [6] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
        [7] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
        [8] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
        [9] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
        [10] => Array
            (
                [TOTAL] => 0
                [YEAR] => 2015
            )
    
    )
    

    Seems uasort can go unstable when issuing multi-leveled sortings while it maintains array index order when they have same values. The talking is that is currently fixed on PHP7 for small size arrays (<16), so if you dare it, may be worth the trying!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀