Question

I have an array like the following:

Array
(
    [0] => Array
        (
            'name' => "Friday"
            'weight' => 6
        )
    [1] => Array
        (
            'name' => "Monday"
            'weight' => 2
        )
)

I would like to grab the last values in that array (the 'weight'), and use that to sort the main array elements. So, in this array, I'd want to sort it so the 'Monday' element appears before the 'Friday' element.

Was it helpful?

Solution

You can use usort as:

function cmp($a, $b) {
   return $a['weight'] - $b['weight'];
}

usort($arr,"cmp");

OTHER TIPS

Can be done using an anonymous function.

Also if your 'weight' is a string use one of the other returns (see the commented out lines):

<?php

$arr = array(
    0 => array (
        'name'   => 'Friday',
        'weight' => 6,
    ),
    1 => array (
        'name'   => 'Monday',
        'weight' => 2,
    ),
);

// sort by 'weight'
usort($arr, function($a, $b) { // anonymous function
    // compare numbers only
    return $a['weight'] - $b['weight'];

    // compare numbers or strings
    //return strcmp($a['weight'], $b['weight']);

    // compare numbers or strings non-case-sensitive
    //return strcmp(strtoupper($a['weight']), strtoupper($b['weight']));
});

var_export($arr);

/*
array (
    0 => array (
        'name'   => 'Monday',
        'weight' => 2,
    ),
    1 => array (
        'name'   => 'Friday',
        'weight' => 6,
    ),
)
*/

You can also use an anonymous function.

usort($items, function($a, $b) {
    return $a['name'] > $b['name'];
});

Agree with usort, I also sometimes use array_multisort (http://ca2.php.net/manual/en/function.usort.php) example 3, sorting database results. You could do something like:

<?php
$days = array(
  array('name' => 'Friday', 'weight' => 6),
  array('name' => 'Monday', 'weight' => 2),
);

$weight = array();
foreach($days as $k => $d) {
  $weight[$k] = $d['weight'];
}

print_r($days);

array_multisort($weight, SORT_ASC, $days);

print_r($days);
?>

Output:

Array
(
    [0] => Array
        (
            [name] => Friday
            [weight] => 6
        )

    [1] => Array
        (
            [name] => Monday
            [weight] => 2
        )

)
Array
(
    [0] => Array
        (
            [name] => Monday
            [weight] => 2
        )

    [1] => Array
        (
            [name] => Friday
            [weight] => 6
        )

)

If the filed you sort by is string like title name,
array_multisort + Flags for Natural Sorting and CaseInSensitivity are the way to go:

$sort_by_title = array();
foreach($items as $item) {
  $sort_by_title [] = $item['title'];
}
array_multisort($sort_by_title , SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE, $items );

NOTE, if the element you are sorting on is a float like .0534 and .0353 (like for a percentage), then you have to multiply both by 1000. not sure why frankly... it appears that usort seems to compare the integer values.

took me awhile to figure that one out...

and 2 tips that may not be immediately obvious:

  1. if your arrays are objects, you can use return $a->weight - $b->weight of course
  2. if you return $b->weight - $a->weight, it will sort desending.

Here's a cool function that might help:

function subval_sort($a,$subkey,$sort) {
    foreach($a as $k=>$v) {
        $b[$k] = strtolower($v[$subkey]);
    }
    if($b)
    {
        $sort($b);
        foreach($b as $key=>$val) {
            $c[] = $a[$key];
        }
        return $c;
    }
}

Send in the array as $a the key as $subkey and 'asort' or 'sort' for the $sort variable

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top