首页 文章

如何按PHP中给定键的值对关联数组进行排序?

提问于
浏览
328

给定这个数组:

$inventory = array(

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

);

我想 sort $inventory's elements by price 得到:

$inventory = array(

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

);

我怎样才能做到这一点?

16 回答

  • 213

    你是对的,你正在寻找的功能是array_multisort() .

    以下是直接从手册中获取的示例,并根据您的情况进行了调整:

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

    PHP 7

    从PHP 7开始,这可以使用usort简洁地完成,使用anonymous function使用spaceship operator来比较元素 .

    你可以这样做一个升序排序:

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

    或者是这样的降序:

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

    要了解其工作原理,请注意 usort 采用用户提供的比较函数,该函数的行为必须如下(来自文档):

    如果第一个参数被认为分别小于,等于或大于第二个参数,则比较函数必须返回小于,等于或大于零的整数 .

    还要注意 <=> ,宇宙飞船运营商,

    如果两个操作数相等则返回0,如果左边更大则返回1,如果右边更大则返回-1

    这正是 usort 所需要的 . 实际上,几乎为https://wiki.php.net/rfc/combined-comparison-operator中的语言添加 <=> 的整个理由是它

    使编写顺序回调与usort()一起使用更容易


    PHP 5.3

    PHP 5.3引入了匿名函数,但还没有太空船运营商 . 我们仍然可以使用 usort 对我们的数组进行排序,但它更冗长,更难理解:

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

    请注意,虽然处理整数值的比较器只返回值的差异(如 $item2['price'] - $item1['price'] )是相当常见的,但在这种情况下我们无法安全地执行此操作 . 这是因为价格是问题提供者示例中的浮点数,但我们传递给 usort 的比较函数必须返回 usort 整数才能正常工作:

    从比较函数返回非整数值(例如float)将导致内部强制转换为回调返回值的整数 . 因此,诸如0.99和0.1之类的值都将被转换为0的整数值,这将将这些值比较为相等 .

    在PHP 5.x中使用 usort 时,这是一个重要的陷阱! My original version of this answer犯了这个错误,然而我却在没有任何人注意到这个严重错误的情况下累积了数十个观点 . 像我这样的缺乏人员可以轻松搞砸比较器功能正是在PHP 7中将易于使用的太空船操作员添加到语言中的原因 .

  • 0

    由于数组元素本身是带有字符串键的数组,因此最好的办法是定义自定义比较函数 . 它非常快速和容易 . 试试这个:

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

    产生以下内容:

    Array
    (
        [0] => Array
            (
                [type] => pork
                [price] => 5.43
            )
    
        [1] => Array
            (
                [type] => fruit
                [price] => 3.5
            )
    
        [2] => Array
            (
                [type] => milk
                [price] => 2.9
            )
    
    )
    
  • 21

    虽然其他人已正确建议使用 array_multisort() ,但出于某种原因,似乎没有答案承认 array_column() 的存在,这可以大大简化解决方案 . 所以我的建议是:

    array_multisort(array_column($inventory, 'price'), SORT_DESC, $inventory);
    
  • -1

    我结束了这个:

    function sort_array_of_array(&$array, $subfield)
    {
        $sortarray = array();
        foreach ($array as $key => $row)
        {
            $sortarray[$key] = $row[$subfield];
        }
    
        array_multisort($sortarray, SORT_ASC, $array);
    }
    

    只需调用该函数,传递数组和第二级数组的字段名称 . 喜欢:

    sort_array_of_array($inventory, 'price');
    
  • -3

    您可以将usort与匿名函数一起使用,例如

    usort($inventory, function ($a, $b) { return strnatcmp($a['price'], $b['price']); });
    
  • 8
    $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");
    }
    

    输出:

    first: pork
    
    pork: 5.43
    fruit: 3.5
    milk: 2.9
    
  • 1

    Was tested on 100 000 records: 以秒为单位的时间(由函数microtime计算) . 仅用于排序键位置的唯一值 .

    Solution of function of @Josh Davis: 上传时间:1.5768740177155

    Mine solution: 暂停时间: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*
    }
    
  • 3

    您可以尝试定义自己的比较函数,然后使用usort .

  • -2

    此功能可重复使用:

    function usortarr(&$array, $key, $callback = 'strnatcasecmp') {
        uasort($array, function($a, $b) use($key, $callback) {
            return call_user_func($callback, $a[$key], $b[$key]);
        });
    }
    

    默认情况下,它在字符串值上运行良好,但如果所有值都是数字,则必须为number comparison function提供回调 .

  • -1

    来自Sort an array of associative arrays by value of given key in php

    uasort(http://php.net/uasort)允许您通过自己定义的函数对数组进行排序 . 在你的情况下,这很简单:

    $array = array(
      array('price'=>'1000.50','product'=>'test1'),
      array('price'=>'8800.50','product'=>'test2'),
      array('price'=>'200.0','product'=>'test3')
    );
    
    function cmp($a, $b) {
      return $a['price'] > $b['price'];
    }
    
    uasort($array, "cmp");
    
  • 460
    //Just in one line custom function
    function cmp($a, $b)
    {
    return (float) $a['price'] < (float)$b['price'];
    }
    @uasort($inventory, "cmp");
    print_r($inventory);
    
    //result
    
    Array
    (
    [2] => Array
        (
            [type] => pork
            [price] => 5.43
        )
    
    [0] => Array
        (
            [type] => fruit
            [price] => 3.5
        )
    
    [1] => Array
        (
            [type] => milk
            [price] => 2.9
        )
    
    )
    
  • 12
    $arr1 = array(
    
        array('id'=>1,'name'=>'aA','cat'=>'cc'),
        array('id'=>2,'name'=>'aa','cat'=>'dd'),
        array('id'=>3,'name'=>'bb','cat'=>'cc'),
        array('id'=>4,'name'=>'bb','cat'=>'dd')
    );
    
    $result1 = array_msort($arr1, array('name'=>SORT_DESC);
    
    $result2 = array_msort($arr1, array('cat'=>SORT_ASC);
    
    $result3 = array_msort($arr1, array('name'=>SORT_DESC, 'cat'=>SORT_ASC));
    
    
    function array_msort($array, $cols)
    {
        $colarr = array();
        foreach ($cols as $col => $order) {
        $colarr[$col] = array();
        foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
    }
    
    $eval = 'array_multisort(';
    
    foreach ($cols as $col => $order) {
        $eval .= '$colarr[\''.$col.'\'],'.$order.',';
    }
    
    $eval = substr($eval,0,-1).');';
    eval($eval);
    $ret = array();
    foreach ($colarr as $col => $arr) {
        foreach ($arr as $k => $v) {
            $k = substr($k,1);
            if (!isset($ret[$k])) $ret[$k] = $array[$k];
            $ret[$k][$col] = $array[$k][$col];
        }
    }
    return $ret;
    
    
    }
    
  • 36

    Complete Dynamic Function 我跳到这里进行关联数组排序,并在http://php.net/manual/en/function.sort.php上找到了这个神奇的功能 . 此函数非常动态,使用指定键按升序和降序排序 .

    通过特定键对数组进行排序的简单功能 . 维护索引关联

    <?php
    
    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;
    }
    
    $people = array(
        12345 => array(
            'id' => 12345,
            'first_name' => 'Joe',
            'surname' => 'Bloggs',
            'age' => 23,
            'sex' => 'm'
        ),
        12346 => array(
            'id' => 12346,
            'first_name' => 'Adam',
            'surname' => 'Smith',
            'age' => 18,
            'sex' => 'm'
        ),
        12347 => array(
            'id' => 12347,
            'first_name' => 'Amy',
            'surname' => 'Jones',
            'age' => 21,
            'sex' => 'f'
        )
    );
    
    print_r(array_sort($people, 'age', SORT_DESC)); // Sort by oldest first
    print_r(array_sort($people, 'surname', SORT_ASC)); // Sort by surname
    
  • 39
    <?php
    
    $inventory = array(
    
       array("type"=>"fruit", "price"=>3.50),
       array("type"=>"milk", "price"=>2.90),
       array("type"=>"pork", "price"=>5.43),
    
    );
    
    
    
    function myfunc($a,$b){
    return strnatcmp($a['price'],$b['price']);
    }
    $result=usort ($inventory,"myfunc");?>
    <pre><?php print_r(array_reverse($inventory)); ?></pre>
    

    简单的解决方案:)

    输出是,

    Array
    (
        [0] => Array
            (
                [type] => pork
                [price] => 5.43
            )
    
        [1] => Array
            (
                [type] => fruit
                [price] => 3.5
            )
    
        [2] => Array
            (
                [type] => milk
                [price] => 2.9
            )
    
    )
    
  • 1

    试试这个:

    asort($array_to_sort, SORT_NUMERIC);
    

    供参考,请参阅:http://php.net/manual/en/function.asort.php

    在这里看到各种排序标志:http://www.php.net/manual/en/function.sort.php

相关问题