2

In an array of arbitrary order and keys, as below

$myArray = array(
    1  => 'foo',
    4  => 'bar',
    6  => 'foobar',
    24 => 'barfoo',
    30 => 'fizz',
    35 => 'buzz',
    50 => 'fizzbuzz'
);

How can I get a segment of the array by a key range, for example, every item with a key between 5 and 40

Something like array_range($myArray, 5, 40);

Expected output: array(6 => 'foobar', 24 => 'barfoo', 30 => 'fizz', 35 => 'buzz')

This is similar to How to use array_filter() to filter array keys? but in this case, I am restricted to PHP 5.5.

Eamonn
  • 418
  • 3
  • 11
  • Are all the array values unique or do you expect duplicates? – edcs Feb 02 '17 at 15:45
  • 1
    Possible duplicate of [PHP: How to use array\_filter() to filter array keys?](http://stackoverflow.com/questions/4260086/php-how-to-use-array-filter-to-filter-array-keys) – random_user_name Feb 02 '17 at 15:45
  • You can array_flip() your array (which swaps the keys and values around), array_filter() the flipped array and then array_flip() the result back. Of course that will only work 100% reliably with arrays that don't contain any duplicate values but if you can meet that requirement then it should work. – GordonM Feb 02 '17 at 16:34

3 Answers3

3

Define a range of keys in an array and then compute the intersection of keys:

$range  = array_flip(range(5, 40));
$result = array_intersect_key($myArray, $range);

One liner:

$result = array_intersect_key($myArray, array_flip(range(5, 40)));

Optionally to fill the range array (I just thought of the other one first and it's shorter):

$range = array_fill_keys(range(5, 40), 1);

If you want specific keys and not a range, just define an array of keys or values and flip:

$range = array_flip(array(6, 24, 50));
//or
$range = array(6=>1, 24=>1, 50=>1);
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
2

If PHP version is under 5.6, upgrade your version of PHP - 5.5 is not even supported any longer. If you can't upgrade PHP, then clearly AbraCadaver's answer is the one to use.

This requires PHP 5.6+, but was answered before the PHP version was clarified in the question, so I will leave it for reference.

Using array_filter - so long as the PHP version is above 5.6:

$allowed_range = [ 'min' => 5, 'max' => 40 ];
$filtered = array_filter(
    $myArray,
    function ( $key ) use ( $allowed_ranged ) {
        return ( $key >= $allowed_range[ 'min' ] && $key <= $allowed_range[ 'max' ] );
    },
    ARRAY_FILTER_USE_KEY
);
Community
  • 1
  • 1
random_user_name
  • 25,694
  • 7
  • 76
  • 115
  • I am the developer, not the system admin. When it's under my control, I exclusively use PHP 7 as an absolute minimum, but things aren't always that way unfortunately. – Eamonn Feb 02 '17 at 15:57
  • Upvoted for prosperity though. Anyone using outdated PHP should update immediately. – Eamonn Feb 02 '17 at 15:58
  • 1
    Understood - I put this here for future visitors as much as anything else, so not any sort of commentary on you or your skills! I am a developer also, and know that we often have our hands tied... – random_user_name Feb 02 '17 at 15:58
  • Google App Engine is stuck on 5.5 so if you're running applications in Google's cloud then you're stuck with that version at least until google pull their finger out. – GordonM Feb 02 '17 at 16:35
  • 1
    @GordonM - wow that's amazing that Google would have people locked down to old unsupported versions :\ – random_user_name Feb 02 '17 at 16:36
  • @cale_b I guess they don't care about software they didn't write themselves. :P But yeah, you'd think a big company that supposedly takes internet security so seriously would know better. – GordonM Feb 02 '17 at 16:38
1

Just iterate the array, and use a condition to build a filtered array (here assuming an inclusive range):

<?php
$in = array(
    1  => 'foo',
    4  => 'bar',
    6  => 'foobar',
    24 => 'barfoo',
    30 => 'fizz',
    35 => 'buzz',
    50 => 'fizzbuzz'
);

$out = [];
foreach($in as $k => $v)
{
    if($k >= 5 && $k <= 40) {
        $out[$k] = $v;
    }
}
var_dump($out);

Output:

array (size=4)
  6 => string 'foobar' (length=6)
  24 => string 'barfoo' (length=6)
  30 => string 'fizz' (length=4)
  35 => string 'buzz' (length=4)
Progrock
  • 7,373
  • 1
  • 19
  • 25