How to sort an array of associative arrays by value of a given key in PHP?

前端 未结 19 1815
清酒与你
清酒与你 2020-11-21 23:34

Given this array:

$inventory = array(

   array(\"type\"=>\"fruit\", \"price\"=>3.50),
   array(\"type\"=>\"milk\", \"price\"=>2.90),
   array(\"         


        
相关标签:
19条回答
  • 2020-11-22 00:12

    try this:

    asort($array_to_sort, SORT_NUMERIC);
    

    for reference see this: http://php.net/manual/en/function.asort.php

    see various sort flags here: http://www.php.net/manual/en/function.sort.php

    0 讨论(0)
  • 2020-11-22 00:13

    You are right, the function you're looking for is array_multisort().

    Here's an example taken straight from the manual and adapted to your case:

    $price = array();
    foreach ($inventory as $key => $row)
    {
        $price[$key] = $row['price'];
    }
    array_multisort($price, SORT_DESC, $inventory);
    

    As of PHP 5.5.0 you can use array_column() instead of that foreach:

    $price = array_column($inventory, 'price');
    
    array_multisort($price, SORT_DESC, $inventory);
    
    0 讨论(0)
  • 2020-11-22 00:15

    PHP 7+

    As of PHP 7, this can be done concisely using usort with an anonymous function that uses the spaceship operator to compare elements.

    You can do an ascending sort like this:

    usort($inventory, function ($item1, $item2) {
        return $item1['price'] <=> $item2['price'];
    });
    

    Or a descending sort like this:

    usort($inventory, function ($item1, $item2) {
        return $item2['price'] <=> $item1['price'];
    });
    

    To understand how this works, note that usort takes a user-provided comparison function that must behave as follows (from the docs):

    The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.

    And note also that <=>, the spaceship operator,

    returns 0 if both operands are equal, 1 if the left is greater, and -1 if the right is greater

    which is exactly what usort needs. In fact, almost the entire justification given for adding <=> to the language in https://wiki.php.net/rfc/combined-comparison-operator is that it

    makes writing ordering callbacks for use with usort() easier


    PHP 5.3+

    PHP 5.3 introduced anonymous functions, but doesn't yet have the spaceship operator. We can still use usort to sort our array, but it's a little more verbose and harder to understand:

    usort($inventory, function ($item1, $item2) {
        if ($item1['price'] == $item2['price']) return 0;
        return $item1['price'] < $item2['price'] ? -1 : 1;
    });
    

    Note that although it's fairly common for comparators dealing with integer values to just return the difference of the values, like $item2['price'] - $item1['price'], we can't safely do that in this case. This is because the prices are floating point numbers in the question asker's example, but the comparison function we pass to usort has to return integers for usort to work properly:

    Returning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback's return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.

    This is an important trap to bear in mind when using usort in PHP 5.x! My original version of this answer made this mistake and yet I accrued ten upvotes over thousands of views apparently without anybody noticing the serious bug. The ease with which lackwits like me can screw up comparator functions is precisely the reason that the easier-to-use spaceship operator was added to the language in PHP 7.

    0 讨论(0)
  • 2020-11-22 00:18

    Was tested on 100 000 records: Time in seconds(calculated by funciton microtime). Only for unique values on sorting key positions.

    Solution of function of @Josh Davis: Spended time: 1.5768740177155

    Mine solution: Spended time: 0.094044923782349

    Solution:

    function SortByKeyValue($data, $sortKey, $sort_flags=SORT_ASC)
    {
        if (empty($data) or empty($sortKey)) return $data;
    
        $ordered = array();
        foreach ($data as $key => $value)
            $ordered[$value[$sortKey]] = $value;
    
        ksort($ordered, $sort_flags);
    
        return array_values($ordered); *// array_values() added for identical result with multisort*
    }
    
    0 讨论(0)
  • 2020-11-22 00:18

    I use uasort like this

    <?php
    $users = [
        [
            'username' => 'joe',
            'age' => 11
        ],
        [
            'username' => 'rakoto',
            'age' => 21
        ],
        [
            'username' => 'rabe',
            'age' => 17
        ],
        [
            'username' => 'fy',
            'age' => 19
        ],    
    ];
    
    
    uasort($users, function ($item, $compare) {
        return $item['username'] >= $compare['username']; 
    });
    
    var_dump($users);
    
    0 讨论(0)
  • 2020-11-22 00:19
    $inventory = 
        array(array("type"=>"fruit", "price"=>3.50),
              array("type"=>"milk", "price"=>2.90),
              array("type"=>"pork", "price"=>5.43),
              );
    
    function pricesort($a, $b) {
      $a = $a['price'];
      $b = $b['price'];
      if ($a == $b)
        return 0;
      return ($a > $b) ? -1 : 1;
    }
    
    usort($inventory, "pricesort");
    // uksort($inventory, "pricesort");
    
    print("first: ".$inventory[0]['type']."\n\n");
    // for usort(): prints milk (item with lowest price)
    // for uksort(): prints fruit (item with key 0 in the original $inventory)
    
    // foreach prints the same for usort and uksort.
    foreach($inventory as $i){
      print($i['type'].": ".$i['price']."\n");
    }
    

    outputs:

    first: pork
    
    pork: 5.43
    fruit: 3.5
    milk: 2.9
    
    0 讨论(0)
提交回复
热议问题