usort基于另一个数组的多重排序数组

时间:2014-09-01 10:01:37

标签: php arrays sorting multidimensional-array usort

我有一个数组,我需要按另一个数组排序2个字段的邮政编码并批准

我可以通过邮政编码对其进行排序,但无法使用已批准的字段进行排序,例如

我需要按60007,60001,60003,60002 排序(按照排序顺序) 所有来自60007和经批准的邮政编码都应该是第一位的

$sortLike=array(60007,60001,60003,60002);
$array1= array(
    array ('ID' => 138,'zip_code' => 60007,'approved' => 1),
    array('ID' => 103,'zip_code' => 60007,'approved' => 0),
    array('ID' => 114,'zip_code' => 60007,'approved' => 1),
    array('ID' => 105,'zip_code' => 60003,'approved' => 0),
    array('ID' => 124,'zip_code' => 60002,'approved' => 0)
)

所以60007和被批准的应该首先超过60007与0(未批准)并且比所有60001批准的所有60001未批准(依据$sortlike这样)这里是完整的PHP代码

<?php
$array1= array(
    array ('ID' => 138,'zip_code' => 60007,'approved' => 1),
    array('ID' => 103,'zip_code' => 60007,'approved' => 0),
    array('ID' => 114,'zip_code' => 60007,'approved' => 1),
    array('ID' => 105,'zip_code' => 60003,'approved' => 0),
    array('ID' => 124,'zip_code' => 60002,'approved' => 0),
    array('ID' => 104,'zip_code' => 60002,'approved' => 1),
    array('ID' => 106,'zip_code' => 60001,'approved' => 0),
    array('ID' => 188,'zip_code' => 60022,'approved' => 0),
    array('ID' => 184,'zip_code' => 60022,'approved' => 1),
);
function sort_results ($a, $b) {
   $sortLike=array(60007,60001,60003,60002);
   if (!in_array ($a['zip_code'], $sortLike)) { return 1; } // Push unknown values at the end of the array
   return array_search($a['zip_code'], $sortLike) > array_search($b['zip_code'], $sortLike);
}

usort ($array1, 'sort_results');
echo "<pre>";
print_r($array1);
echo "</pre>";

4 个答案:

答案 0 :(得分:1)

usort($array_data, array($sort_obj = new cmpArray('array_key'), "cmp__"));
class cmpArray
     {

         var $key;

         function __construct($key)
         {
             $this->key = $key;
         }

         function cmp__($a, $b)
         {
             $key = $this->key;
             if($a[$key] == $b[$key])
                 return 0;

             return (($a[$key] > $b[$key]) ? 1 : -1);
         }

     }

答案 1 :(得分:1)

我猜你问你怎么也可以按'approved'排序,因为你的代码目前缺少这个。

此问题的解决方案是定义检查输入数组$array1的键的顺序。

所以你需要先检查zip_code。如果得到结果!= 0,您可以立即返回。但如果结果为== 0(邮政编码相同),则需要检查第二个密钥(在您的情况下为'approved')。

$array1= array(
    array ('ID' => 138,'zip_code' => 60007,'approved' => 1),
    array('ID' => 103,'zip_code' => 60007,'approved' => 0),
    array('ID' => 114,'zip_code' => 60007,'approved' => 1),
    array('ID' => 105,'zip_code' => 60003,'approved' => 0),
    array('ID' => 124,'zip_code' => 60002,'approved' => 0),
    array('ID' => 104,'zip_code' => 60002,'approved' => 1),
    array('ID' => 106,'zip_code' => 60001,'approved' => 0),
    array('ID' => 188,'zip_code' => 60022,'approved' => 0),
    array('ID' => 184,'zip_code' => 60022,'approved' => 1),
);
function sort_results ($a, $b) {
    $sortLike=array(60007,60001,60003,60002);
    if (!in_array ($a['zip_code'], $sortLike)) { return 1; } // Push unknown values at the end of the array
    $zip_res = array_search($a['zip_code'], $sortLike) - array_search($b['zip_code'], $sortLike); // check zip_code order 
    if($zip_res == 0){ // if the zip_codes are equal
        $zip_res = $b['approved'] - $a['approved']; // sort by the 'approved' key
    }
    return $zip_res;
}

<强> //修改

你可以使用lamda函数将$sortLike移出这个函数(需要PHP&gt; = 5.3):

$sortLike=array(60007,60001,60003,60002);
$sort_results = function ($a, $b) use ($sortLike){ // create lambda function with "use" keyword
    if (!in_array ($a['zip_code'], $sortLike)) { return 1; } // Push unknown values at the end of the array
    $zip_res = array_search($a['zip_code'], $sortLike) - array_search($b['zip_code'], $sortLike);
    if($zip_res == 0){
        $zip_res = $b['approved'] - $a['approved'];
    }
    return $zip_res;
};

usort ($array1,$sort_results); // pass lambda function in
echo "<pre>";
print_r($array1);
echo "</pre>";
die();

答案 2 :(得分:0)

<?php
$array1= array(
array ('ID' => 138,'zip_code' => 60007,'approved' => 1),
array('ID' => 103,'zip_code' => 60007,'approved' => 0),
array('ID' => 114,'zip_code' => 60007,'approved' => 1),
array('ID' => 105,'zip_code' => 60003,'approved' => 0),
array('ID' => 124,'zip_code' => 60002,'approved' => 0),
array('ID' => 104,'zip_code' => 60002,'approved' => 1),
array('ID' => 106,'zip_code' => 60001,'approved' => 0),
array('ID' => 188,'zip_code' => 60022,'approved' => 0),
array('ID' => 184,'zip_code' => 60022,'approved' => 1),
);

function sort_it ($a) {
$sortedarr = array();
$sortLike=array(60007,60001,60003,60002);
foreach($sortLike as $el){
    array_push($sortedarr,getElements($a,$el));
}
}



function getElements($arr,$e){
$newarr = array();
foreach($arr as $val){
    if($val['approved'] == '1' && $val['zip_code'] == $e){
    $newarr[] = $val;
    }
}
foreach($arr as $val){
    if($val['approved'] == '0' && $val['zip_code'] == $e){
    $newarr[] = $val;
    }
}
return $newarr;
}

$array2 = sort_it($array1);
echo "<pre>";
print_r($array1);
echo "</pre>";
echo "<pre>";
print_r($array2);
echo "</pre>";
?>

答案 3 :(得分:0)

usort() PHP Demo)

$priorityZips = array_flip([60007, 60001, 60003, 60002]);
$priorityCount = count($priorityZips);

usort($rows, function($a, $b) use ($priorityZips, $priorityCount) {
    return [
               $priorityZips[$a['zip_code']] ?? $priorityCount,
               $a['zip_code'],
               $b['approved']
           ]
           <=>
           [
               $priorityZips[$b['zip_code']] ?? $priorityCount,
               $b['zip_code'],
               $a['approved']
           ];
});

usort() PHP> = v7.4:(Demo

$priorityZips = array_flip([60007, 60001, 60003, 60002]);
$priorityCount = count($priorityZips);

usort($rows, fn($a, $b) =>
    [
        $priorityZips[$a['zip_code']] ?? $priorityCount,
        $a['zip_code'],
        $b['approved']
    ]
    <=>
    [
        $priorityZips[$b['zip_code']] ?? $priorityCount,
        $b['zip_code'],
        $a['approved']
    ]
);

array_multisort() PHP Demo)

$priorityZips = array_flip([60007, 60001, 60003, 60002]);
$priorityCount = count($priorityZips);

array_multisort(
    array_map(
        function($row) use ($priorityZips, $priorityCount) {
            return $priorityZips[$row['zip_code']] ?? $priorityCount;
        },
        $rows
    ),
    array_column($rows, 'zip_code'),
    array_column($rows, 'approved'),
    SORT_DESC,
    $rows
);

array_multisort() PHP> = v7.4:(Demo

$priorityZips = array_flip([60007, 60001, 60003, 60002]);
$priorityCount = count($priorityZips);

array_multisort(
    array_map(
        fn($row) => $priorityZips[$row['zip_code']] ?? $priorityCount,
        $rows
    ),
    array_column($rows, 'zip_code'),
    array_column($rows, 'approved'),
    SORT_DESC,
    $rows
);

在上面的代码段中,我将您的输入数组称为$rows

可以通过多种方式执行此任务,但是我已经展示了一些我认为最干净/最易读的内容。如果性能对您的应用程序至关重要,我鼓励您使用自己的真实数据进行基准测试;否则,请选择最适合长期维护的代码段。

在低于7.4的PHP版本中,使用use()将变量传递到自定义函数范围中。在PHP7.4及更高版本中,“ arrow function syntax”在自定义函数中剥离了大量语法,并允许输入变量而无需使用use()

spaceship operator” /“三向比较运算符”(<=>)使构建多条件排序的MUCH与一堆条件块相比更加简洁明了。太空船运算符将同步处理数组中的元素,并返回正确求值的-101。还将数字字符串视为数字。

我翻转了优先邮政编码的查找数组,以使“ null coalescing operator”(??)能够快速返回优先级值,或者默认为大于查找中最高整数的数字。

关于要比较的usort数组的结构,您可能希望看到this answer更加详细。