Dan Lugg
Dan Lugg

Reputation: 20621

Multi-dimensional array to key/value dictionary; returned from function, no control structures

Fairly simple; I'm just curious if there's a better way to accomplish this.

Given an array as follows:
(the result of preg_match_all() with PREG_SET_ORDER)

$matches = array(2) {
  [0]=>
  array(5) {
    [0]=>
    string(8) "key=foo;"
    ["key"]=>
    string(3) "key"
    [1]=>
    string(3) "key"
    ["value"]=>
    string(3) "foo"
    [2]=>
    string(3) "foo"
  }
  [1]=>
  array(5) {
    [0]=>
    string(12) "pattern=bar;"
    ["key"]=>
    string(7) "pattern"
    [1]=>
    string(7) "pattern"
    ["value"]=>
    string(3) "bar"
    [2]=>
    string(3) "bar"
  }
}

I'd like to extract into an array, the following:

array(2) {
  ["key"]=>
  string(3) "foo"
  ["pattern"]=>
  string(3) "bar"
}

Essentially producing an associative array of $array[$i]['key'] => $array[$i]['value'] for each $i.
(If that sounds confusing, sorry, it's late)

Anyway, this is trivial; however, I'm trying to accomplish this using PHP core array_* functions, that return the resulting array (sorry array_walk).

No foreach, or other looping control structures.

Right now, I've got it down to this:

\array_combine(\array_map(function($match) {
        return (string) $match['key'];
    }, $matches), \array_map(function($match) {
        return (string) $match['value'];
    }, $matches))

Which works, however it's not exactly succinct; I don't like it having to array_map twice -- once for keys, once for values.

Is there a more elegant solution, to extracting nested values from a well-formed multi-dimensional array, into a one-dimensional key/value pair dictionary?

Upvotes: 0

Views: 3186

Answers (1)

Yoshi
Yoshi

Reputation: 54659

With php v5.3+:

because of:

5.3.0 Changed initial to allow mixed, previously integer.

http://php.net/manual/en/function.array-reduce.php

$matches = array(
  array(
                'key=foo;',
    'key' =>    'key',
                'key',
    'value' =>  'foo',
                'foo',
  ),
  array(
                'pattern=bar;',
    'key' =>    'pattern',
                'pattern',
    'value' =>  'bar',
                'bar',
  ),
);

$a = array_reduce($matches, function ($b, $v) {
  return $b + array($v['key'] => $v['value']);
}, array());

print_r($a);

/*
Array
(
    [key] => foo
    [pattern] => bar
)
*/

Upvotes: 2

Related Questions