0

Given the following array:

$array = array(
    'note' => array('test', 'test1', 'test2', 'test3', 'test4'),
    'year' => array('2011','2010', '2012', '2009', '2010'),
    'type' => array('journal', 'conference', 'editorial', 'conference','conference'),
);

Array can be easily transposed if it is easier (using the following function):

for ($i = 0; $i < count($array['type']); $i++)
  foreach ($array as $key => $value)
    $temp[$i][$key] = $value[$i];

print_r($temp);

And I want to sort it using the following criteria:

  1. An array $sortby = ('journal', 'editorial', 'conference')
  2. After sorting in categories I would like to sort by year DESC for every category.

Desired result:

Array
(
[note] => Array
    (
        [0] => test
        [1] => test2
        [2] => test1
        [3] => test4
        [4] => test3
    )

[year] => Array
    (
        [0] => 2011
        [1] => 2012
        [2] => 2010
        [3] => 2010
        [4] => 2009
    )

[type] => Array
    (
        [0] => journal
        [1] => editorial
        [2] => conference
        [3] => conference
        [4] => conference
    )

)
6
  • That is not a good way of grouping related items. Commented Jun 20, 2012 at 15:58
  • This seems like you made it unnecessarily difficult by storing these things in a 2-d array. Commented Jun 20, 2012 at 16:00
  • So is it impossible to do that? Because I found out that every solution using PHP sorting functions (they are using quicksort) it is imposible to return correct results Commented Jun 20, 2012 at 16:00
  • @salamis Each "entry" (note, year, and type) should be its own object; don't split them across different arrays. Commented Jun 20, 2012 at 16:01
  • You shouldn't be building your multidimensional arrays like that. Each item should have its own note,year,type. Commented Jun 20, 2012 at 16:01

2 Answers 2

2

If you transpose your input array, then you'll be able to sort by column at a time.

$Array = array(
    array('note' => 'test1', 'year' => '2011', 'type' => 'journal'),
    array('note' => 'test2', 'year' => '2012', 'type' => 'editorial'),
    array('note' => 'test3', 'year' => '2012', 'type' => 'conference'),
    array('note' => 'test4', 'year' => '2012', 'type' => 'conference'),
    array('note' => 'test5', 'year' => '2012', 'type' => 'conference')
);

Let's sort them by year value.

function array_sort_by_column(&$arr, $col, $dir = SORT_DESC) {
    $sort_col = array();
    foreach ($arr as $key=> $row) {
        $sort_col[$key] = $row[$col];
    }
    return array_multisort($sort_col, $dir, $arr);
}

array_sort_by_column($Array, 'year');
print_r($Array);

Output:

Array
(
    [0] => Array
        (
            [note] => test2
            [year] => 2012
            [type] => editorial
        )

    [1] => Array
        (
            [note] => test3
            [year] => 2012
            [type] => conference
        )

    [2] => Array
        (
            [note] => test4
            [year] => 2012
            [type] => conference
        )

    [3] => Array
        (
            [note] => test5
            [year] => 2012
            [type] => conference
        )

    [4] => Array
        (
            [note] => test1
            [year] => 2011
            [type] => journal
        )

)

Sort them by note value.

array_sort_by_column($Array, 'note');
print_r($Array);

Output:

Array
(
    [0] => Array
        (
            [note] => test5
            [year] => 2012
            [type] => conference
        )

    [1] => Array
        (
            [note] => test4
            [year] => 2012
            [type] => conference
        )

    [2] => Array
        (
            [note] => test3
            [year] => 2012
            [type] => conference
        )

    [3] => Array
        (
            [note] => test2
            [year] => 2012
            [type] => editorial
        )

    [4] => Array
        (
            [note] => test1
            [year] => 2011
            [type] => journal
        )

)

Sort by type value.

array_sort_by_column($Array, 'type');
print_r($Array);

Output:

Array
(
    [0] => Array
        (
            [note] => test1
            [year] => 2011
            [type] => journal
        )

    [1] => Array
        (
            [note] => test2
            [year] => 2012
            [type] => editorial
        )

    [2] => Array
        (
            [note] => test3
            [year] => 2012
            [type] => conference
        )

    [3] => Array
        (
            [note] => test4
            [year] => 2012
            [type] => conference
        )

    [4] => Array
        (
            [note] => test5
            [year] => 2012
            [type] => conference
        )

)
Sign up to request clarification or add additional context in comments.

1 Comment

The result seems correct but I think if the sortby array was different then the result would have been wrong. Please check again the 1st criterion.
0

Use a single array_multisort() call. Write your rules as leading parameters, then write an subarrays that have not been passed in in their original (reference-able) form. The below executes the sorting process as:

  • sort by type priority ASC, then
  • sort by year DESC, then
  • sort by note ASC, then
  • sort by type ASC

The last two patameters are "coming along for the ride" -- they are mentioned so that they are mutated in accordance with earlier parameter sorting. Demo

$array = [
    'note' => ['test', 'test1', 'test2', 'test3', 'test4'],
    'year' => ['2011', '2010', '2012', '2009', '2010'],
    'type' => ['journal', 'conference', 'editorial', 'conference', 'conference'],
];
$priorities = array_flip(['journal', 'editorial', 'conference']);

array_multisort(
    array_map(fn($t) => $priorities[$t] ?? PHP_INT_MAX, $array['type']),
    $array['year'],
    SORT_DESC,
    $array['note'],
    $array['type']
);
var_export($array);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.