简体   繁体   中英

Nearest array element by key in reverse order

I have custom code where I get nearest user from array by array key:

$users = [
    "4" => "John",
    "7" => "Alex",
    "13" => "Smith",
    "95" => "Taylor"
];

$id = 9;

$nearestUserByIdInReverseOrder = false;

foreach($users as $userId => $name) {
    if($id >= $userId) {
        $nearestUserByIdInReverseOrder = $name;
    }
}

echo $nearestUserByIdInReverseOrder;

When I change var $id to 3 or smaller number then don't get result. How to get first element of array when $id smaller then it. And can be shorted or optimized code if I've incorrect logic operation in my code? Maybe this possible without looping.

Here is demo

If you want to get the first value in your array if $id is less than any of the array keys, you can initialise $nearestUserByIdInReverseOrder to the first element in the array using reset :

$users = [
    "4" => "John",
    "7" => "Alex",
    "13" => "Smith",
    "95" => "Taylor"
];

$id = 3;

$nearestUserByIdInReverseOrder = reset($users);
foreach($users as $userId => $name) {
    if($id >= $userId) {
        $nearestUserByIdInReverseOrder = $name;
    }
}

echo $nearestUserByIdInReverseOrder;

Output:

John

Demo on 3v4l.org

Note that for this (or your original code) to work, the keys must be in increasing numerical order. If they might not be, ksort the array first:

ksort($users);

Based on your explanation you want to reverse the comparison logic. Also, you want to break out of the loop when you have found the key that is greater, or else you will always get the greatest number:

foreach($users as $userId => $name) {
    if($userId > $id) {
        $nearestUserByIdInReverseOrder = $name;
        break;
    }
}

I have removed the = as that would return 4 for $id = 4 instead of 7 . If that is not the desired behavior then add it back.

If the array is not guaranteed to be in ascending order of keys then you need to sort first:

ksort($users);
function findClosest($array, $index) {
    ksort($array);
    $idx = array_keys($array)[0];
    foreach ($array as $key => $value) {
        if ($key > $index) return $array[$idx];
        $idx = $key;
    }
}

$users = [
    "13" => "Smith",
    "4" => "John",
    "7" => "Alex",
    "95" => "Taylor"
];

$id = 3;

echo findClosest($users, $id);

You could use array_keys() (props to Jeto ) on the array, search for the closest number in that ( this for reference ) and then grab the name based on that.

This would work and the logic is pretty simple, although there may be better solutions. I'm sure someone can use it at some point for something :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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