0

Is there a better / more elegant / more efficient way of doing this?

I have an array that I'm searching the keys for a value that either matches or is the greatest value that is less than the search value. Hope that makes sense.

My current method is a bit of a brute force attempt that is fine for a small collection of data but this function will need to run many times with a large array.

$needle = '2013-04-04';    

$haystack = array    (
                     '2013-01-01'   => 1,
                     '2013-04-03'   => 2,
                     '2013-04-05'   => 3,
                     '2013-07-23'   => 4,
                     '2013-09-12'   => 5,
                     '2013-10-18'   => 6,
                     '2013-11-01'   => 7
                     );

krsort($haystack);

foreach ($haystack as $k => $v)
    {
    $possibleMatch = $k;
    if ($needle >= $k) break;
    }

return $possibleMatch

Thanks in advance

Gavin
  • 2,123
  • 1
  • 15
  • 19

2 Answers2

0

Looking at your data, it looks like your array is sorted. If it is not, stay with brute force. I think a fast way to get your result if there is no exact match is a bisection (also called binary search or dichotomy). Pseudo code :

Take a key in the middle of your array. If the key is inferior to your search, search in the sub-array that starts with this key If the key is superior to your search, search in the sub-array that ends with this key Repeat until the array is of size 1.

Like this :

  +----------------------------------------------------------------------------------------+
  |                                                                                        |
  +----------------------------------------------------------------------------------------+
  +----------------------------------------+ +---------------------------------------------+
  |                                        | |                                             |
  +----------------------------------------+ +---------------------------------------------+
  +------------------+ +-------------------+
  |                  | |                   |
  +------------------+ +-------------------+
                       +--------+ +--------+
                       |        | |        |
                       +--------+ +--------+
                       +---++---+
                       |   ||   |
                       +---++---+
                       +-+
                       | |
                       +-+

                      desired value

Warning : DO NOT, I repeat, DO NOT search for bisection on google images. It hurts.

greg0ire
  • 22,714
  • 16
  • 72
  • 101
0

Use a modified binary search. One sample is here - modify binary search to find the next bigger item than the key; can be easily customized to suit your needs.

Community
  • 1
  • 1
Amit
  • 1,836
  • 15
  • 24