59

I have an associative array of data and I have an array of keys I would like to remove from that array (while keeping the remaining keys in original order -- not that this is likely to be a constraint).

I am looking for a one liner of php to do this.
I already know how I could loop through the arrays but it seems there should be some array_map with unset or array_filter solution just outside of my grasp.

I have searched around for a bit but found nothing too concise.

To be clear this is the problem to do in one line:

//have this example associative array of data
$data = array(
    'blue'   => 43,
    'red'    => 87,
    'purple' => 130,
    'green'  => 12,
    'yellow' => 31
);

//and this array of keys to remove
$bad_keys = array(
    'purple',
    'yellow'
);

//some one liner here and then $data will only have the keys blue, red, green
Peyman Mohamadpour
  • 17,954
  • 24
  • 89
  • 100
hackartist
  • 5,172
  • 4
  • 33
  • 48
  • 2
    Make a function to do it: `remove_keys_from_array($array, $keys)`. And look at that, it takes up only one line! – Blender Jun 14 '12 at 04:46
  • I know but I bet there is some way to use the php functions to do it... but fair enough, it does take only one line – hackartist Jun 14 '12 at 04:47

3 Answers3

145

$out =array_diff_key($data,array_flip($bad_keys));

All I did was look through the list of Array functions until I found the one I needed (_diff_key).

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 2
    ok the array_flip trick is what I didn't know about. Thanks! – hackartist Jun 14 '12 at 04:50
  • 1
    I had to think about this one for a mo. The point is `$bad_keys = array(0=>'purple',1=>'yellow')` so the keys in the array_flip are 'purple','yellow'. Hence the diff_key works. Neat. Thanks Kolink. – TerryE Jun 14 '12 at 09:43
  • I once needed to remove by value (not keys) and I ended up with this: `$myArr = array(5, 25, 5, 30);` ... THEN ... `$myArr =& array_diff_key($myArr, array_flip(array_keys($myArr, 5)));` – Stphane Jan 08 '15 at 10:55
37

The solution is indeed the one provided by Niet the Dark Absol. I would like to provide another similar solution for anyone who is after similar thing, but this one uses a whitelist instead of a blacklist:

$whitelist = array( 'good_key1', 'good_key2', ... );
$output = array_intersect_key( $data, array_flip( $whitelist ) );

Which will preserve keys from $whitelist array and remove the rest.

Community
  • 1
  • 1
Peyman Mohamadpour
  • 17,954
  • 24
  • 89
  • 100
0

This is a blacklisting function I created for associative arrays.

if(!function_exists('array_blacklist_assoc')){

    /**
     * Returns an array containing all the entries from array1 whose keys are not present in any of the other arrays when using their values as keys.
     * @param array $array1 The array to compare from
     * @param array $array2 The array to compare against
     * @return array $array2,... More arrays to compare against
     */

    function array_blacklist_assoc(Array $array1, Array $array2) {
        if(func_num_args() > 2){
            $args = func_get_args();
            array_shift($args);
            $array2 = call_user_func_array('array_merge', $args);
        } 
        return array_diff_key($array1, array_flip($array2));
    }
}

$sanitized_data = array_blacklist_assoc($data, $bad_keys);
TarranJones
  • 4,084
  • 2
  • 38
  • 55