41

Simple one, I was just wondering if there is a clean and eloquent way of returning all values from an associative array that do not match a given key(s)?

$array = array('alpha' => 'apple', 'beta' => 'banana', 'gamma' => 'guava');

$alphaAndGamma = arrayExclude($array, array('alpha'));
$onlyBeta      = arrayExclude($array, array('alpha', 'gamma'));

function arrayExclude($array, Array $excludeKeys){
    foreach($array as $key => $value){
        if(!in_array($key, $excludeKeys)){
            $return[$key] = $value;
        }
    }
    return $return;
}

This is what I'm (going to be) using, however, are there cleaner implementations, something I missed in the manual perhaps?

Dan Lugg
  • 20,192
  • 19
  • 110
  • 174

9 Answers9

58

Although, this question is too old and there are several answer are there for this question, but I am posting a solution that might be useful to someone.

You may get the all array elements from provided input except the certain keys you've defined to exclude using:

$result = array_diff_key($input, array_flip(["SomeKey1", "SomeKey2", "SomeKey3"]));

This will exclude the elements from $input array having keys SomeKey1, SomeKey2 and SomeKey3 and return all others into $result variable.

Dev
  • 6,570
  • 10
  • 66
  • 112
45

You could just unset the value:

$alphaAndGamma = $array;
unset($alphaAndGamma['alpha']);

Edit: Made it clearer. You can copy an array by assigning it to another variable.

or in a function:

function arrayExclude($array, Array $excludeKeys){
    foreach($excludeKeys as $key){
        unset($array[$key]);
    }
    return $array;
}
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Thanks **Felix Kling**; Yes, however that modifies the original array. – Dan Lugg Feb 28 '11 at 21:22
  • @TomcatExodus: Yes, but you can assign the array to an other variable before and unset the value(s) on this one. Assignment copies the array. – Felix Kling Feb 28 '11 at 21:23
  • I don't want to sound finnicky, yet your solution `unset`s from the source array. The OP wants the array-without-this-and-that-key returned from a function. +1 for the obvious solution, though. – Linus Kleen Feb 28 '11 at 21:24
  • @TomcatExodus, so just copy it first - `$alphaAndGamma = $array; unset($alphaAndGamma['alpha']);` – Czechnology Feb 28 '11 at 21:24
  • @Linus Kleen: Copying an array is easy... I made it more clear though. – Felix Kling Feb 28 '11 at 21:27
  • If you're using unset, you might hit a situation where that key doesn't exist, right? That would be the one reason I could see against this approach...but that really depends on the use case, I suppose. – dmcnelis Feb 28 '11 at 21:27
  • **@Felix Kling**; True, wrapped in a function like yours appears to be best (I would imagine considerably faster than mine also, given a massive array) I believe that's the answer I'm looking for. While I was aware of `unset`-ting array elements, I was hoping there was an implementation of this I had somehow missed in the manual. – Dan Lugg Feb 28 '11 at 21:28
  • **@dmcnelis**; Will `unset` throw a notice? – Dan Lugg Feb 28 '11 at 21:29
  • 1
    @TomcatExodus, @dmcnelis: Just tested it, no notice will be thrown. Hence, testing is not necessary. – Felix Kling Feb 28 '11 at 21:31
  • **@Felix Kling**; Thank you! Also, should I call this `arrayExclude` or `array_exclude` in my library? Just wondering if in your experience it's best to maintain PHPs conventions when creating core-like functions. – Dan Lugg Feb 28 '11 at 21:47
  • @TomcatExodus: I would call it `array_exclude`. But you really should have a look at [@linepogl's answer](http://stackoverflow.com/questions/5147691/return-all-array-elements-except-for-a-given-key/5147755#5147755). Together with `array_flip`, this is a very nice approach. – Felix Kling Feb 28 '11 at 21:55
  • **@Felix Kling**; I took a look at it, and (to me) it seems a bit more convoluted, having to pass the `$keys` as keys and flip. Wrapped in a function like yours/mine, perhaps, though I doubt it would be faster. I'll do a test and see. – Dan Lugg Feb 28 '11 at 22:00
16

Use array_diff_key():

$array = array('alpha' => 'apple', 'beta' => 'banana', 'gamma' => 'guava');

$alphaAndGamma = array_diff_key($array, array('alpha'=>0));
$onlyBeta      = array_diff_key($array, array('alpha'=>0, 'gamma'=>0));

EDIT: I added =>0s.

linepogl
  • 9,147
  • 4
  • 34
  • 45
  • 1
    You have to create the second array differently then. You have to use `array_flip(array('alpha'))`. But nice approach +1. More elegant than mine, but considering all functions, not necessarily faster... but that needed to be tested. – Felix Kling Feb 28 '11 at 21:34
  • Oh and a second remark: This will only work if all the keys that have to be unset are also in the array. But we have not enough information about that. – Felix Kling Feb 28 '11 at 21:43
  • 1
    @Felix Kling. Actually, you are wrong. See the example in the documentation: http://www.php.net/manual/en/function.array-diff-key.php – linepogl Feb 28 '11 at 21:46
  • @linepogl: True, sorry. Sometimes PHP functions work a little different than you might expect from their names. I would upvote you twice if I could. – Felix Kling Feb 28 '11 at 21:53
  • **Thanks linepogl**; I'll have to benchmark this against Felix's. – Dan Lugg Feb 28 '11 at 22:01
12

if you wanted Laravel way, The Arr::except method removes the given key / value pairs from an array:

use Illuminate\Support\Arr;

$array = ['name' => 'Desk', 'price' => 100];

$filtered = Arr::except($array, ['price']);

// ['name' => 'Desk']

@source https://laravel.com/docs/8.x/helpers#method-array-except

Moode Osman
  • 1,715
  • 18
  • 17
3

Simple function here, using two arrays, the actual array and an array of keys that should be excluded. Could also easily be made into a one liner if we exclude the function.

function array_except(array $array,array $except) {

 return array_filter($array,fn($key) => !in_array($key,$except),ARRAY_FILTER_USE_KEY);

}
Anoxy
  • 873
  • 7
  • 17
2
$alphaAndGamma = $array;
unset($alphaAndGamma['alpha']);

$onlyBeta = $array;
unset($onlyBeta['alpha'], $onlyBeta['gamma']);
steveo225
  • 11,394
  • 16
  • 62
  • 114
1

There have been a few discussions about speed when using in_array. From what I've read, including this comment1, using isset is faster than in_array.

In that case your code would be:

function arrayExclude($array, array $excludeKeys){

    $return = [];

    foreach($array as $key => $value){
        if(!isset($excludeKeys[$key])){
            $return[$key] = $value;
        }
    }
    return $return;
}

That would be slightly faster, and may help in the event that you're needing to process large datasets.

Rich Bradshaw
  • 71,795
  • 44
  • 182
  • 241
dmcnelis
  • 2,913
  • 1
  • 19
  • 28
0

You can easily remove an array item by its key using this..

unset($array['key']); 

DEMO http://codepad.org/EA9vTwzR

Dutchie432
  • 28,798
  • 20
  • 92
  • 109
-2

array_diff_assoc could help. So i.e. you could use

$onlyBeta = array_diff_assoc($array, array('alpha', 'gamma'))
frabala
  • 369
  • 4
  • 13