0

I have an array that its values are associate arrays. I need sort this array based on keys;

$list = array (
    array("post_id"=>"2","date"=>"2015","title"=>"title2"),
    array("post_id"=>"4","date"=>"2017","title"=>"title4"),
    array("post_id"=>"3","date"=>"2016","title"=>"title3"),
    array("post_id"=>"1","date"=>"2014","title"=>"title1")
);

For example sorting this array by post_id which means turn that array to this:

$list = array (
    array("post_id"=>"1","date"=>"2014","title"=>"title1"),
    array("post_id"=>"2","date"=>"2015","title"=>"title2"),
    array("post_id"=>"3","date"=>"2016","title"=>"title3"),
    array("post_id"=>"4","date"=>"2017","title"=>"title4")


);

I searched this forum and find this code:

function array_sort($array, $on, $order=SORT_ASC){

$new_array = array();
$sortable_array = array();

if (count($array) > 0) {
    foreach ($array as $k => $v) {
        if (is_array($v)) {
            foreach ($v as $k2 => $v2) {
                if ($k2 == $on) {
                    $sortable_array[$k] = $v2;
                }
            }
        } else {
            $sortable_array[$k] = $v;
        }
    }

    switch ($order) {
        case SORT_ASC:
            asort($sortable_array);
            break;
        case SORT_DESC:
            arsort($sortable_array);
            break;
    }

    foreach ($sortable_array as $k => $v) {
        $new_array[$k] = $array[$k];
    }
}

return $new_array;}

but I cant understand what is it exactly doing. the topic link is: Sort PHP multi-dimensional array based on key?

Community
  • 1
  • 1

6 Answers6

1

You're not sorting by key, so the example you found won't work for you. A simple usort will do it;

$list = array (
    array("post_id"=>"2","date"=>"2015","title"=>"title2"),
    array("post_id"=>"4","date"=>"2017","title"=>"title4"),
    array("post_id"=>"3","date"=>"2016","title"=>"title3"),
    array("post_id"=>"1","date"=>"2014","title"=>"title1")
);

function sortPosts($a, $b)
{
    if ($a['post_id'] == $b['post_id']) {
        return 0;
    }
    return ($a['post_id'] < $b['post_id']) ? -1 : 1;
}


usort($list, "sortPosts");

This passes your $lists array into a function and compares each of its values - you can see we're comparing the ['post_id'] value for each.

As the post_id's are strings in your original array, you may need to typecast these as integers, but see how you go.

Tom
  • 4,257
  • 6
  • 33
  • 49
1

Most elegant usually is to use the usort() function combined with a closure.

Take a look at this simple demonstration:

<?php

$list = [
    ["post_id"=>"2","date"=>"2015","title"=>"title2"],
    ["post_id"=>"4","date"=>"2017","title"=>"title4"],
    ["post_id"=>"3","date"=>"2016","title"=>"title3"],
    ["post_id"=>"1","date"=>"2014","title"=>"title1"]
];

usort(
  $list,
  function($a, $b) {
    return $a['post_id'] < $b['post_id'];
  }
);
print_r($list); // First output, descending order

usort(
  $list,
  function($a, $b) {
    return $a['post_id'] > $b['post_id'];
  }
);
print_r($list); // Second output, ascending order

Note the reversed comparison operator in the two calls, < versus >...


The output of that obviously is:

First output, descending order:

Array
(
    [0] => Array
        (
            [post_id] => 4
            [date] => 2017
            [title] => title4
        )

    [1] => Array
        (
            [post_id] => 3
            [date] => 2016
            [title] => title3
        )

    [2] => Array
        (
            [post_id] => 2
            [date] => 2015
            [title] => title2
        )

    [3] => Array
        (
            [post_id] => 1
            [date] => 2014
            [title] => title1
        )

)

Second output, ascending order:

Array
(
    [0] => Array
        (
            [post_id] => 1
            [date] => 2014
            [title] => title1
        )

    [1] => Array
        (
            [post_id] => 2
            [date] => 2015
            [title] => title2
        )

    [2] => Array
        (
            [post_id] => 3
            [date] => 2016
            [title] => title3
        )

    [3] => Array
        (
            [post_id] => 4
            [date] => 2017
            [title] => title4
        )

)
arkascha
  • 41,620
  • 7
  • 58
  • 90
1

I use this function :

function aasort (&$array, $key) {
    $sorter=array();
    $ret=array();
    reset($array);
    foreach ($array as $ii => $va) {
        $sorter[$ii]=$va[$key];
    }
    asort($sorter);
    foreach ($sorter as $ii => $va) {
        $ret[$ii]=$array[$ii];
    }
    $array=$ret;
    return $array;
}

$list = array (
    array("post_id"=>"2","date"=>"2015","title"=>"title2"),
    array("post_id"=>"4","date"=>"2017","title"=>"title4"),
    array("post_id"=>"3","date"=>"2016","title"=>"title3"),
    array("post_id"=>"1","date"=>"2014","title"=>"title1")
);

$outputArray = aasort($list,"post_id");
Bhavin Solanki
  • 1,364
  • 11
  • 27
1

That probably wasn't the best answer to chose from that question. Just extract the column to sort on, and sort that to sort the original:

array_multisort(array_column($list, 'post_id'), SORT_ASC, $list);
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
1

You can use following code:

<?php
$list = array (
    array("post_id"=>"2","date"=>"2015","title"=>"title2"),
    array("post_id"=>"4","date"=>"2017","title"=>"title4"),
    array("post_id"=>"3","date"=>"2016","title"=>"title3"),
    array("post_id"=>"1","date"=>"2014","title"=>"title1")
);

$sorted = array_orderby($list, 'post_id', SORT_ASC);

echo "<pre>";
print_r($sorted);

function array_orderby()
{
    $args = func_get_args();
    $data = array_shift($args);
    foreach ($args as $n => $field) {
        if (is_string($field)) {
            $tmp = array();
            foreach ($data as $key => $row)
                $tmp[$key] = $row[$field];
            $args[$n] = $tmp;
            }
    }
    $args[] = &$data;
    call_user_func_array('array_multisort', $args);
    return array_pop($args);
}
?>

It will produce following output:

Array
(
    [0] => Array
        (
            [post_id] => 1
            [date] => 2014
            [title] => title1
        )

    [1] => Array
        (
            [post_id] => 2
            [date] => 2015
            [title] => title2
        )

    [2] => Array
        (
            [post_id] => 3
            [date] => 2016
            [title] => title3
        )

    [3] => Array
        (
            [post_id] => 4
            [date] => 2017
            [title] => title4
        )

)
Manish Joy
  • 476
  • 3
  • 17
1

The function in OP question does:

  • first collects all values via $on from the subarray (first foreach) and binds it to the $sortable_array via original_array key $k. Like $list[0]['post_id']; is collect in: $sortable_array[0];
  • After all values are collected, the array will be sorted DESC or ASC (see switch) with asort, that keeps the index=>value connection. So $sortable_array looks like: Before [0=>2,1=>4,2=>3,3=>1] After [3=>1,0=>2,2=>3,1=>4]
  • So now the values are sorted and the index can be used in the next step.
  • In the last foreach a new array is generated. The index $k from the $sortable_array is used to get the subsarrays from the original_array in the new order.

note: This part if (is_array($v)) makes the function behavior not predictable, because it takes just the $v if $v is not an subarray else it would take data from the subarray!!!

JustOnUnderMillions
  • 3,741
  • 9
  • 12