0

Is there a one liner for finding an integer key equal to or greater than a given index? To make things clear, here's an example of an array I'm working with.

array( 4294967295 => 'LONGTEXT'
     , 16777215   => 'MEDIUMTEXT'
     , 65535      => 'TEXT'
     , 255        => 'TINYTEXT' );

As some of you may recognize, these are MySQL column definition types. Let's say I'm given an integer 500, how can I quickly/compactly find the next key of 65535 which maps to 'TEXT'?

Currently I iterate the array using foreach (hence highest values first) and track the last key. But, due to the number of arrays and data types I'm dealing with, the function has become bloated.

Twifty
  • 3,267
  • 1
  • 29
  • 54
  • maybe arrays are not the best data structure for this –  Apr 15 '14 at 20:34
  • @Dagon Then what would you suggest? I chose an array since they can easily be redefined in derived classes. – Twifty Apr 15 '14 at 20:35
  • Whats the motivation behind requesting a one-line solution? – Mike B Apr 15 '14 at 20:37
  • @MikeB I have 2 `switch` statements which I'd like to reduce to one. sth like `if ( $key = array_search( highest ) )` would help. – Twifty Apr 15 '14 at 20:40
  • 1
    @Waldermort Readability and maintability go out the door when coders try to be "clever" with 1 line solutions. – Mike B Apr 15 '14 at 20:41
  • @MikeB lol, I know. Hence the `compactly` in the question. Really I'm just wondering if there's an easier method than my current loop and track. – Twifty Apr 15 '14 at 20:42
  • Possible duplicate: http://stackoverflow.com/questions/5464919/php-nearest-value-from-an-array – Aziz Saleh Apr 15 '14 at 20:59
  • @AzizSaleh Not a duplicate, that's finding next highest value, I'm trying to find next highest key within a pre-ordered array. – Twifty Apr 15 '14 at 21:10
  • @Waldermort Always read the answers as well as the question. Many answers on that thread and many others on the column are for sorted arrays. – Aziz Saleh Apr 15 '14 at 21:42

1 Answers1

2

This is compact and should work:

$sizes = array_filter(array_keys($array), function($element) use ($size) { return $element >= $size; });
$array[array_pop($sizes)];

This will emit an undefined index error if no type large enough exists in $array. I really wouldn't consider it optimal - the best solution is rarely the shortest possible.

Consider using something like this, which is more robust:

function getType(array $types, $desiredSize) { // $types should be sorted by key asc
    foreach($array as $length => $type) {
        if($length >= $desiredSize) {
            return $type;
        }
    }

    return null; // no type large enough
}

$types = array(
        4294967295 => 'LONGTEXT',
        16777215 => 'MEDIUMTEXT',
        65535 => 'TEXT',
        255 => 'TINYTEXT');
ksort($types); // or hardcode it in asc order

echo getType($types, 500); // TEXT
George Brighton
  • 5,131
  • 9
  • 27
  • 36
  • That's exactly what I had in my mind. As a minor improvement, I would change `return null;` to `end($types);`, so it uses the largest one available. But that may not be what the OP wants. Oh well. – Amal Murali Apr 15 '14 at 20:58
  • Hmmm. Not sure if I agree with `end()` - I guess it depends on the OP's needs. They may want to throw an exception if no type is large enough rather than just use the largest available and truncate... – George Brighton Apr 15 '14 at 21:01
  • This may work. Since I have to handle default values for missing sizes and arrays with only a single entry, calling this within a my `switch` would be a lot easier. Thanks :) – Twifty Apr 15 '14 at 21:08