简体   繁体   English

PHP:如何检查数组中最接近给定数字的项?

[英]PHP: How to check which item in an array is closest to a given number?

I need to check which item in an array array( 300, 600, 900, 1200 ) is closest to the number I have stored in a variable $number . 我需要检查数组array( 300, 600, 900, 1200 )中的哪个项目最接近我存储在变量$number

I've looked through the PHP manual for either an approach or a function which will do this for me but my research has found nothing. 我在PHP手册中查找了可以为我完成此工作的方法或功能,但是我的研究没有发现任何问题。 Hoping someone can suggest something. 希望有人可以提出一些建议。

If the numbers in the array are always sorted in ascending order, you can loop through once checking distance as you go and soon as you start moving away from your number, return the last good number. 如果数组中的数字始终按升序排序,则可以在检查距离时循环遍历,一旦离开数字就返回最后一个合适的数字。 Something like this: 像这样:

<?php
$number = mt_rand(1, 1200);
$array = array(300, 600, 900, 1200);

function closest($number, $array){
    //infinite distance to start
    $dist = INF;
    //remember our last value
    $last = false;

    foreach($array as $v){
        //get our current distance
        $dist2 = abs($number - $v);

        //check if we are getting further than last number was
        if($dist2 > $dist){
            //return our last value
            return $last;
        }
        //set our new distance
        $dist = $dist2;
        //set our last value for next iteration
        $last = $v;
    }
    return $last;
}

echo "<pre>";
var_dump($number);
var_dump(closest($number, $array));

Will output: 将输出:

Input: int(522)
Output: int(600)

Demo: http://codepad.viper-7.com/NjcdP0 演示: http//codepad.viper-7.com/NjcdP0

If the values are not sorted, you will need to loop over each value to get a distance and then find the smallest distance. 如果未对值进行排序,则需要遍历每个值以获取距离,然后找到最小距离。 Something like: 就像是:

<?php
$number = mt_rand(1, 1200);
$array = array(300, 600, 900, 1200);

function closest($number, $array){
    //find distances to number
    $dist = array_map(
        function($val) use ($number) {
            return abs($number - $val);
        },
        $array);
    //flip array so distance is key
    $dist = array_flip($dist);
    //sort distance by key
    ksort($dist);

    //get key for shortest distance
    $key = array_values($dist)[0];

    return $array[$key];
}

echo "<pre>";
echo "Input: ";
var_dump($number);
echo "Output: ";
var_dump(closest($number, $array));

Outputs: 输出:

Input: int(677)
Output: int(600)

Demo: http://codepad.viper-7.com/N5nv0v 演示: http//codepad.viper-7.com/N5nv0v

I'm sure this is not the fastest way to do this, but it can be written simply using usort . 我敢肯定这不是最快的方法,但是可以使用usort编写。 After you sort the array by absolute difference from the target number, the closest value will be the first one: 在按照与目标编号的绝对差对数组进行排序后,最接近的值将是第一个:

usort($your_array, function($a, $b) use ($number) {
    if ($a == $b) { return 0; }
    return abs($number - $a) > abs($number - $b) ? 1 : -1;
});

$closest = reset($your_array);

In PHP 7, the usort callback can be simplified with the combined comparison operator. 在PHP 7中,可以使用组合比较运算符简化usort回调。

usort($your_array, function($a, $b) use ($number) {
    return abs($number - $a) <=> abs($number - $b);
});

You must iterate through and store both current result and difference, like this: 您必须遍历并存储当前结果和差异,如下所示:

function closest_number(array $array, $number) {
    $result     = null;
    $difference = null;

    foreach ($array as $element) {    
        if ($difference === null || abs($element - $number) < $difference) {
            $difference = abs($element - $number);
            $result     = $element;
        }
    }

    return $result;
}

Here some magic code: 这里有一些魔术代码:

$arr = [300, 600, 900, 1200];
$number = 920;
$deltas = array_reduce(
    $arr, 
    function($t, $v) use ($number) { 
        $t[$v] = abs($v - $number); 
        return $t; 
    },
    []
);
asort($deltas);
echo array_keys($deltas)[0];

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

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