29

I want to generate a list of the second level of keys used. Each record does not contain all of the same keys. But I need to know what all of the keys are. array_keys() doesn't work, it only returns a list of numbers.

Essentially the output Im looking for is:

action, id, validate, Base, Ebase, Ftype, Qty, Type, Label, Unit

I have a large multi-dimensional array that follows the format:

Array
(
    [0] => Array
        (
            [action] => A
            [id] => 1
            [validate] => yes
            [Base] => Array
                (
                    [id] => 2945
                )

            [EBase] => Array
                (
                    [id] => 398
                )

            [Qty] => 1
            [Type] => Array
                (
                    [id] => 12027
                )

            [Label] => asfhjaflksdkfhalsdfasdfasdf
            [Unit] => asdfas
        )

    [1] => Array
        (
            [action] => A
            [id] => 2
            [validate] => yes
            [Base] => Array
                (
                    [id] => 1986
                )

            [FType] => Array
                (
                    [id] => 6
                )

            [Qty] => 1
            [Type] => Array
                (
                    [id] => 13835
                )

            [Label] => asdssdasasdf
            [Unit] => asdger
        )
)

Thanks for the help!

user103219
  • 3,209
  • 11
  • 39
  • 50

11 Answers11

25
<?php

// Gets a list of all the 2nd-level keys in the array
function getL2Keys($array)
{
    $result = array();
    foreach($array as $sub) {
        $result = array_merge($result, $sub);
    }        
    return array_keys($result);
}

?>

edit: removed superfluous array_reverse() function

J.C. Inacio
  • 4,442
  • 2
  • 22
  • 25
14
array_keys(call_user_func_array('array_merge', $a));

Merge all values and retrieve the resulting keys.

9

One liner:

$keys=array_unique(array_reduce(array_map('array_keys',$data),'array_merge',[]));

Or in a function:

function get_array_children_keys($data) {
    return array_unique(
        array_reduce(array_map('array_keys', $data), 'array_merge', [])
    );
}

Now lets break this down with an example, here is some sample data:

[
    ['key1' => 0],
    ['key1' => 0, 'key2' => 0],
    ['key3' => 0]
]

Starting with the inner most function, we run array_map with the array_keys function:

array_map('array_keys', $data)

This gives us the keys of from all child arrays

[
    ['key1'],
    ['key1', 'key2'],
    ['key3']
]

Then we run the array_reduce on the data with the array_merge callback and an empty array as the initial value:

array_reduce(..., 'array_merge', []);

This converts our multiple arrays into 1 flat array:

[
    'key1',
    'key1',
    'key2',
    'key3'
]

Now we strip out our duplicates with array_unique:

array_unique(...)

And end up with all our keys:

[
    'key1',
    'key2',
    'key3'
]
Sy Holloway
  • 419
  • 4
  • 5
7
foreach($bigArray as $array){    
    foreach($array as $key=>$value){
        echo $key;
    }
}

That should do what you want.

brettkelly
  • 27,655
  • 8
  • 56
  • 72
  • thanks inkedmn - I had first attempted your first version (prior to your edit) and it obviously didn't work. This one worked just fine, then a simple if statement to check for duplicates and I had my data. – user103219 Sep 21 '09 at 17:59
  • This one was perfect for my needs as well. I was trying to get nested key values that looked ``` [applications] => Array ( [0] => Array ( [id] => 2 [name] => WordPress [short_name] => wordpress [deploy_name] => WordPress on Ubuntu 18.04 x64 ``` This worked to get me the id and name as key => values ``` foreach ($apps as $app) { foreach ($app as $key=>$value) { $vultr_apps_nice[$value['id']] = $value['name']; } } ``` – Mike R Apr 11 '21 at 06:51
6

What about something like this :

$your_keys = array_keys($your_array[0]);

Of course, this is considering all sub-arrays have the same keys ; in this case, you only need the keys of the first sub-array (no need to iterate over all first-level sub-arrays, I guess)


And, as a shortened / simplified example :

$your_array = array(
    array(
        'action' => 'A',
        'id' => 1,
        'base' => array('id' => 145),
    ),
    array(
        'action' => 'B',
        'id' => 2,
        'base' => array('id' => 145),
    ),
    array(
        'action' => 'C',
        'id' => 3,
        'base' => array('id' => 145),
    )
);

$your_keys = array_keys($your_array[0]);
var_dump($your_keys);

Will get you :

array
  0 => string 'action' (length=6)
  1 => string 'id' (length=2)
  2 => string 'base' (length=4)

You can the use implode to get the string you asked for :

echo implode(', ', $your_keys);

will get you :

action, id, base

ie, the list of the keys of the first sub-array.

Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
1
function  __getAll2Keys($array_val){
        $result = array();
        $firstKeys = array_keys($array_val);
        for($i=0;$i<count($firstKeys);$i++){
            $key = $firstKeys[$i];
            $result = array_merge($result,array_keys($array_val[$key]));
        }
        return $result;
    }

try this function. It will return as you want.

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
1

While @raise answers provides a shortcut, it fails with numeric keys. The following should resolve this:

$secondKeys=array_unique(call_user_func_array('array_merge', array_map('array_keys',$a)));

array_map('array_keys',$a) : Loop through while getting the keys

...'array_merge'... : Merge the keys array

array_unique(... : (optional) Get unique keys.

I hope it helps someone.

UPDATE:

Alternatively you can use

$secondKeys=array_unique(array_merge(...array_map('array_keys', $a)));

That provides same answer as above, and much faster.

McAngujo
  • 115
  • 2
  • 8
1

My proposal, similar to this answer but faster and using spread operator (PHP 5.6+).

array_merge(...array_values($fields))

if you want move names to array values and reset keys to 0..n just use array_keys in last step.

array_keys(array_merge(...array_values($fields)))

  • The first level is indexed in the OP's question, so `array_values()` is not necessary for this specific question. – mickmackusa Jun 15 '21 at 23:11
0

Maybe you can use array_map function, which allows you to avoid array iteration and return an array with the keys you need as values.

will be like this

$newArray = array_map(function($value){return array_keys($value);},$yourArray);

var_dump($newArray);

array (size=2)
  0 => 
    array (size=9)
      0 => string 'action' (length=6)
      1 => string 'id' (length=2)
      2 => string 'validate' (length=8)
      3 => string 'Base' (length=4)
      4 => string 'EBase' (length=5)
      5 => string 'Qty' (length=3)
      6 => string 'Type' (length=4)
      7 => string 'Label' (length=5)
      8 => string 'Unit' (length=4)
  1 => 
    array (size=9)
      0 => string 'action' (length=6)
      1 => string 'id' (length=2)
      2 => string 'validate' (length=8)
      3 => string 'Base' (length=4)
      4 => string 'FType' (length=5)
      5 => string 'Qty' (length=3)
      6 => string 'Type' (length=4)
      7 => string 'Label' (length=5)
      8 => string 'Unit' (length=4)
snaphuman
  • 311
  • 4
  • 7
0

With this function you can get all keys from a multidimensional array

function arrayKeys($array, &$keys = array()) {        
        foreach ($array as $key => $value) {
            $keys[] = $key;
            if (is_array($value)) {                
                $this->arrayKeys($value, $keys);
            }
        }
        return $keys;
}
Giovani
  • 2,459
  • 1
  • 21
  • 16
0

Only if all records have the same keys you could do:

$firstItem = reset($array);
$keys = array_keys($firstItem);

Obviously, this is not the correct answer to this specific question, where the records have different keys. But this might be the question you find when looking how to retrieve second level keys from an array where all keys are the same (I did). If all the record have the same keys, you can simply use the first item in the array with reset() and get the keys from the first item with array_keys().

Dirk J. Faber
  • 4,360
  • 5
  • 20
  • 58