开发者

Sorting by key in a multidimensional array with php [duplicate]

This question already has answers here: Closed 11 years ago.

Possible Duplicate:

Sorting multidimensional array in PHP

How can I sort by key in a multidimensional array?

For instance, below is the array I print from my db, where the latest comes first - December, November, October, etc and 2011, 2010, 2009, etc

Array
(
    [0] => Array
        (
            [URL] => september 2011
            [Title] => September 2011
            [Date] => 8
            [Month] => 9
            [Year] => 2011
        )

    [1] => Array
        (
            [URL] => january 2011
            [Title] => January 2011
            [Date] => 1
            [Month] => 2
            [Year] => 2011
        )

    [2] => Array
        (
            [URL] => february 2011
            [Title] => February 2011
            [Date] => 4
            [Month] => 1
            [Year] => 2011
        )

    [3] => Array
        (
            [URL] => november 2011
            [Title] => November 2011
            [Date] => 23
            [Month] => 11
            [Year] => 2010
        )

    [4] => Array
        (
            [URL] => april 2011
            [Title] => April 2011
            [Date] => 23
            [Month] => 4
            [Year] => 2010
        )

)

But I need it to be like this, October, November, December, etc and 2011, 2010, 2009, etc - note the months are sorted by the oldest comes first but the years are still sorted by the latest comes first.

So the array should be sorted like this,

Array
(

    [2] => Array
        (
            [URL] => february 2011
            [Title] => 开发者_JS百科February 2011
            [Date] => 4
            [Month] => 1
            [Year] => 2011
        )

    [1] => Array
        (
            [URL] => january 2011
            [Title] => January 2011
            [Date] => 1
            [Month] => 2
            [Year] => 2011
        )

    [0] => Array
        (
            [URL] => september 2011
            [Title] => September 2011
            [Date] => 8
            [Month] => 9
            [Year] => 2011
        )

    [4] => Array
        (
            [URL] => april 2010
            [Title] => April 2010
            [Date] => 23
            [Month] => 4
            [Year] => 2010
        )

    [3] => Array
        (
            [URL] => november 2010
            [Title] => November 2010
            [Date] => 23
            [Month] => 11
            [Year] => 2010
        )
)

Is that possible?


Generic solution to sort arrays of arrays with multiple keys

Based on my answer to this question, here is a very generic solution that you can use in lots of situations.

Limitation: Requires PHP >= 5.3 to work, due to the presence of anonymous functions.

New and improved, now with descending sort support

function make_comparer() {
    $criteriaNames = func_get_args();
    $comparer = function($first, $second) use ($criteriaNames) {
        // Do we have anything to compare?
        while(!empty($criteriaNames)) {
            // What will we compare now?
            $criterion = array_shift($criteriaNames);

            // Used to reverse the sort order by multiplying
            // 1 = ascending, -1 = descending
            $sortOrder = 1; 
            if (is_array($criterion)) {
                $sortOrder = $criterion[1] == SORT_DESC ? -1 : 1;
                $criterion = $criterion[0];
            }

            // Do the actual comparison
            if ($first[$criterion] < $second[$criterion]) {
                return -1 * $sortOrder;
            }
            else if ($first[$criterion] > $second[$criterion]) {
                return 1 * $sortOrder;
            }

        }

        // Nothing more to compare with, so $first == $second
        return 0;
    };

    return $comparer;
}

How to use it

To sort by year ascending:

uasort($array, make_comparer('Year'));

To sort by year ascending, then by month ascending:

uasort($array, make_comparer('Year', 'Month'));

To sort by year descending, then by month ascending:

uasort($array, make_comparer(array('Year', SORT_DESC), 'Month'));

This last one is what you 're after.


Assuming that the data you would have provided in your question would have been actually correct (taking Year, Month, Date as base to create a sort on), you can first index the array by those values and the sort the main array. I'm just writing it, otherwise you might misread the output of the Demo, the URL/Titles do not correspond to the numerical values given, but it just works:

// create an index by date
foreach($data as $k=>$v)
{
    $index[$k] = sprintf('%04d-%02d-%02d', $v['Year'], $v['Month'], $v['Date']);
}

// sort data based on the index
array_multisort($index, SORT_DESC, $data);


How about:

Data:

$arr = Array (
    Array (
        'URL' => 'september 2011',
        'Title' => 'September 2011',
        'Date' => 8,
        'Month' => 9,
        'Year' => 2011,
    ),
    Array (
        'URL' => 'january 2011',
        'Title' => 'January 2011',
        'Date' => 1,
        'Month' => 2,
        'Year' => 2011,
    ),
    Array (
        'URL' => 'february 2011',
        'Title' => 'February 2011',
        'Date' => 4,
        'Month' => 1,
        'Year' => 2011,
    ),
    Array (
        'URL' => 'november 2011',
        'Title' => 'November 2011',
        'Date' => 23,
        'Month' => 11,
        'Year' => 2010,
    ),
    Array (
        'URL' => 'april 2011',
        'Title' => 'April 2011',
        'Date' => 23,
        'Month' => 4,
        'Year' => 2010,
    ),
);

code:

function compare($a, $b) {
    if ($a['Year'] == $b['Year']) {
      return ($a['Month'] - $b['Month']);
    } else {
        return ($b['Year'] - $a['Year']);
    }
}    
usort($arr, 'compare');
print_r($arr);    

output:

Array
(
[0] => Array
    (
        [URL] => february 2011
        [Title] => February 2011
        [Date] => 4
        [Month] => 1
        [Year] => 2011
    )

[1] => Array
    (
        [URL] => january 2011
        [Title] => January 2011
        [Date] => 1
        [Month] => 2
        [Year] => 2011
    )

[2] => Array
    (
        [URL] => september 2011
        [Title] => September 2011
        [Date] => 8
        [Month] => 9
        [Year] => 2011
    )

[3] => Array
    (
        [URL] => april 2011
        [Title] => April 2011
        [Date] => 23
        [Month] => 4
        [Year] => 2010
    )

[4] => Array
    (
        [URL] => november 2011
        [Title] => November 2011
        [Date] => 23
        [Month] => 11
        [Year] => 2010
    )

)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜