简体   繁体   English

如何根据多个条件对数组进行排序?

[英]How to sort array based on multiple criteria?

I'm trying to sort an array prioritizing the closest macros value to the optimal values, ie the element best matching the criteria is id of 200 (but is sorted), looks like all the "points" goes to the prev element instead.我正在尝试对数组进行排序,将最接近的宏值优先于最佳值,即最符合条件的元素是 id 200(但已排序),看起来所有“点”都转到prev元素。

function sorter(array $array, $optimal, $minMax){
    usort($array, function($prev, $curr) use($optimal, $minMax){
    
    $points = ['prev' => 0, 'curr' => 0];

    foreach($curr['macros'] as $macro => $value){                       
        if($value > $minMax[$macro]["minimum"] && $value <= $optimal[$macro]){
            if($macro === "protein"){
                $points['curr'] += 2;
            }
            
            if($macro === "carb" && $value < $prev["macros"][$macro]){
                $points['curr'] += 1;
            }
            
            ++$points['curr'];  
        } else {
            ++$points['prev'];
        }
    }
    
    if($points['prev'] === $points['curr']) return 0;

    return $points['prev'] < $points['curr'] ? -1 : 1;
});

return $array;
}

The protein has a higher priority, with carbs coming second. protein的优先级更高, carbs次之。

http://sandbox.onlinephpfunctions.com/code/77fc35f2fb0b60de9271f7e934a5a8a4aa3b25a3 http://sandbox.onlinephpfunctions.com/code/77fc35f2fb0b60de9271f7e934a5a8a4aa3b25a3

From your description, it sounds like you want to sort by the closeness of the protein value to optimal, breaking ties by using the lowest carb value.根据您的描述,您似乎想根据protein值与最佳值的接近程度进行排序,通过使用最低的carb值来打破关系。 This can be done by taking the abs of the difference between actual and optimal protein values, and if equal, comparing the carb values to find the least:这可以通过获取实际和最佳protein值之间的差异的abs来完成,如果相等,则比较carb值以找到最小值:

function sorter(array $array, $optimal, $minMax){
    usort($array, function ($a, $b) use ($optimal, $minMax) {
        // check closeness of protein to optimal
        $apo = abs($a['macros']['protein'] - $optimal['protein']);
        $bpo = abs($b['macros']['protein'] - $optimal['protein']);
        // if not equally close, return the closest
        if ($apo != $bpo) return $apo <=> $bpo;
        // same protein difference to optimal, return the one with least carbs
        return $a['macros']['carb'] <=> $b['macros']['carb'];
    });
    return $array;
}

For your sample data this returns:对于您的示例数据,这将返回:

Array
(
    [0] => Array
        (
            [id] => 200
            [macros] => Array
                (
                    [calorie] => 443.21
                    [fat] => 35.95
                    [carb] => 3.86
                    [protein] => 24.3
                )
        )
    [1] => Array
        (
            [id] => 3
            [macros] => Array
                (
                    [calorie] => 472.07
                    [fat] => 38.4
                    [carb] => 9.46
                    [protein] => 18.25
                )
        )
    [2] => Array
        (
            [id] => 19
            [macros] => Array
                (
                    [calorie] => 455.22
                    [fat] => 42.08
                    [carb] => 5.25
                    [protein] => 15.81
                )
        )
    [3] => Array
        (
            [id] => 18
            [macros] => Array
                (
                    [calorie] => 457.73
                    [fat] => 41.92
                    [carb] => 5.61
                    [protein] => 10.94
                )
        )
    [4] => Array
        (
            [id] => 9
            [macros] => Array
                (
                    [calorie] => 445.37
                    [fat] => 41.15
                    [carb] => 9.25
                    [protein] => 10.13
                )
        )
    [5] => Array
        (
            [id] => 1
            [macros] => Array
                (
                    [calorie] => 487.98
                    [fat] => 48.79
                    [carb] => 7.35
                    [protein] => 8.06
                )
        )
)

Demo on 3v4l.org 3v4l.org 上的演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM