1

What's the best way of searching an array for a number within a range? e.g. between 1000 and 1500.

<?php
$numbers = array(1105,2140,3170);

$needle = **value between 1000 and 1500**;

if (in_array($needle, $numbers)) {
  echo "Match found";
} else {
  echo "Match not found";
}
?>

In this case, this would return 'Match found' as 1105 is between 1000 and 1500.

Can I set a range for the $needle variable?

5
  • in_array looks incorrect. Commented Feb 14, 2020 at 14:51
  • You want every value in array check if it is between 1000 and 1500? Commented Feb 14, 2020 at 14:51
  • Do you want to know what the matches are or just that at least one match exists? Commented Feb 14, 2020 at 14:57
  • best in what way? Commented Feb 14, 2020 at 18:33
  • Did you give up? Commented Feb 18, 2020 at 14:14

3 Answers 3

2

What's the best way of searching an array for a number within a range. To answer this, there are 2 approaches as mentioned below:

Approach #1:

You can use a simple foreach loop to get all values from your unordered data which lie in the range.

<?php

$numbers = array(1105,2140,3170);

$start = 1000;
$end = 1500;

$result = [];

foreach($numbers as $num){
    if($num >= $start && $num <= $end) $result[] = $num;
}

print_r($result);

Demo: https://3v4l.org/D1Rfu

Approach #2:(recommended for future lookups)

You can sort your data and use binary search to get the starting point of where your numbers start falling in the range of start and end for faster lookups. Then, you can just look from that index till the index you get a higher number or reach the end of the array.

<?php

$numbers = array(1105,2140,3170,1000,1500,1501);

$start = 1000;
$end  = 1500;
$start_index = -1;

sort($numbers);

$low = 0; $high = count($numbers) - 1;

while($low <= $high){
    $mid = intval(($low + $high) / 2);
    if($numbers[$mid] > $end){
        $high = $mid - 1;
    }else if($numbers[$mid] < $start){
        $low = $mid + 1;
    }else{
        $start_index = $mid;
        $high = $mid - 1;
    }
}

$result = [];
for($i = $start_index; $i < count($numbers); ++$i){
    if($numbers[$i] > $end) break;
    $result[] = $numbers[$i];
}

print_r($result);

Demo: https://3v4l.org/WcgXv

Sign up to request clarification or add additional context in comments.

1 Comment

@revo Thanks. Yes, first approach is the best, however if there are frequent lookups for different ranges, approach 2 is better.
1

Yes, you can create a range and use it as the "needle", but not using in_array. You can create a range and compute the intersection of the numbers array. To just check for any match:

$numbers = array(1105, 2140, 3170);
$needle  = range(1000, 1500);

if (array_intersect($numbers, $needle)) {
  echo "Match found";
} else {
  echo "Match not found";
}

Or to get the possible match(es):

$numbers = array(1105, 2140, 3170);
$needle  = range(1000, 1500);
$result  = array_intersect($numbers, $needle);

Or you can filter out the ones not in the range:

$numbers = array(1105, 2140, 3170);
$min = 1000;
$max = 1500;
$result  = array_filter($numbers, function($v) use($min, $max) {
                                     return $v >= $min && $v <= $max;
                                 });

You will get an empty array if there are no matches in either case. Also, you don't state what you want if there is more than one, but you'll get an array in either case so you could use current for one or min and/or max instead:

$one = current(array_intersect($numbers, $needle));
$min = min(array_intersect($numbers, $needle));
$max = max(array_intersect($numbers, $needle));

1 Comment

Thanks. The first option did the trick. I hadn't come across array_intersect before.
-1

There is no built-in function for these purpose. So create a function that will help you.

function searchOnRange(array $stack, $min=0, $max=0)
{
    // Loop through each value of array
    foreach($stack as $value){
        // CHeck value is between the given range
        if(($value >= $min) && ($value <= $max)){
            echo "Match found - ".$value;
        } else {
            echo "Match not found - ".$value;
        }
    }
}

$numbers = array(1105,2140,3170);
searchOnRange($numbers, 1000, 1500);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.