与usort一起使用时的功能组合?

时间:2014-09-24 14:22:12

标签: php

我有一个包含天气值的数组。我现在有一个工作的PHP脚本按温度对数组进行排序,然后拉出温度的最大值,然后再按压力对数组进行排序,得到最大压力值。

function compare_pressure($a, $b)
{
    return strnatcmp($a['pressure'], $b['pressure']);
}

function compare_temp($a, $b)
{
    return strnatcmp($a['temp'], $b['temp']);
}

usort($table, 'compare_pressure');
$mypress = $table[0]['pressure'];

usort($table, 'compare_temp');
$mytemp = $table[0]['temp'];

我现在正在尝试将上述功能结合起来,以便我不必为每次比较编写一个新的功能,但是当与usort一起使用时,我似乎没有任何运气。

我需要这样的东西,它不起作用:(

function compare_temp($a, $b, $value)
{
    return strnatcmp($a[$value], $b[$value]);
}

 usort($table, 'compare_temp', 'temp');

4 个答案:

答案 0 :(得分:1)

按优先顺序排列的方式很多:

// Method 1 -- by object
class Comparitor {
    public function __construct($key) {
        $this->key = $key;
    }
    public function compare($a, $b) {
        return strnatcmp($a[$this->key], $b[$this->key]);
    }
}
usort($table, [new Comparitor('temp'), 'compare']);

// Method 2 -- anonymous function
function compare_by_key($a, $b, $key) {
    return strnatcmp($a[$key], $b[$key]);
}
usort($table, function ($a, $b) { return compare_by_key($a, $b, 'temp'); });

// Method 3 -- by global
function compare_by_global_key($a, $b) {
    global $key;
    return strnatcmp($a[$key], $b[$key]);
}
$key = 'temp';
usort($table, 'compare_by_global_key');    

如果您只需要最大值,则可以使用:

function aggregate_by_key($table, $key, $aggregate = 'max') {
    return $aggregate(array_column($table, $key));
}
$maxTemp = aggregate_by_key($table, 'temp', 'max');
$minTemp = aggregate_by_key($table, 'temp', 'min');
$sumTemp = aggregate_by_key($table, 'temp', 'array_sum');

答案 1 :(得分:1)

由于您正在查找最大温度/压力值,而不是整个记录,请先提取值,然后排序:

$temps = array_column($weather, 'temp');
natsort($temps);
$max_temp = array_pop($temps);

参考:array_columnshim for PHP 5.4-

否则,无需对数组进行排序以找到最大值:

function max_by($ary, $fn) {
    $max = reset($ary);
    foreach($ary as $item)
        $max = $fn($max, $item) > 0 ? $max : $item;
    return $max;
}

然后:

$record_with_max_temp = max_by($weather, function($a, $b) {
    return strnatcmp($a['temp'], $b['temp']);
});

这将返回整个记录,而不仅仅是值。

答案 2 :(得分:0)

function createComparisonFunction($key) {
    return function ($a, $b) use ($key) {
        return strnatcmp($a[$key], $b[$key]);
    };
}

usort($table, createComparisonFunction('pressure'));
usort($table, createComparisonFunction('temp'));

说完了,我宁愿用这种方法开始:

$max = array_reduce(
    $table,
    function (array $max, array $value) {
        if (strnatcmp($max['temp'], $value['temp']) < 0) {
            $max['temp'] = $value['temp'];
        }
        if (strnatcmp($max['pressure'], $value['pressure']) < 0) {
            $max['pressure'] = $value['pressure'];
        }
        return $max;
    },
    ['temp' => null, 'pressure' => null]
);

echo $max['temp'];
echo $max['pressure'];

我不确定为什么你真的需要strnatcmp,这些值应该是整数,这会简化回调函数:

    function (array $max, array $value) {
        $max['temp']     = max($max['temp'], $value['temp']);
        $max['pressure'] = max($max['pressure'], $value['pressure']);
        return $max;
    }

答案 3 :(得分:0)

我很想创建一个包含整个过程的类:

class WeatherData{

    private $max_values;

    public function __construct($weather_array, $elements){

        foreach ($weather_array as $weather_item) {
            foreach($elements as $element){
                if(!isset($this->max_values[$element])){
                    $this->max_values[$element] = $weather_item[$element];
                }else{
                    if($this->max_values[$element] < $weather_item[$element]){
                        $this->max_values[$element] = $weather_item[$element];
                    }
                }
            }
        }    
    }

    public function __get($key){
        return $this->max_values[$key];
    }

}

$wa = array(
    array('pressure'=>11, 'temp'=>2),
    array('pressure'=>1, 'temp'=>22),
    array('pressure'=>7, 'temp'=>21),
    array('pressure'=>22, 'temp'=>33),
    array('pressure'=>16, 'temp'=>8),
);
$elements = array(
    'temp', 'pressure'
);
$wd = new WeatherData($wa, $elements);

echo 'max temp: '. $wd->temp . ' max pressure :' . $wd->pressure;

实例:http://codepad.viper-7.com/kobe1Z