Ordered array to associative array, odd values ​​as keys

Pretty simple:

// turn array('foo', 'bar', 'hello', 'world'); // into array('foo' => 'bar', 'hello' => 'world'); 

Now I am using:

 do{ $arrayOut[current($arrayIn)] = next($arrayIn); }while(next($arrayIn)); 

I am wondering if there is a way to do this without the $arrayOut intermediate variable. I could write a function, but this is the only use case, and I'm trying to keep the script uncluttered. I'm just wondering if there is something that I missed in the documents that would serve this purpose.


Values ​​come from the routing path:

 route/to/controller/action/key1/value1/key2/value2 

It exploded and, in the end, after using other components, I was left with ('key1', 'value1', 'key2', 'value2', ...)


Thank you for your understanding and suggestions. Long Ears won this one for a brief approach, which when expanded to more than "1 line" is not terribly cryptic (I don't think so, at least)

However, with regard to the Long Ears proposal, perhaps my desire for semantically accurate code with minimal detail became better than me, and I chased daisies, trying to preserve my variable “pollutant-free” scope to rephrase myself.

+4
source share
4 answers

You can make your existing code a little more efficient (removes one function call per iteration, for one at the beginning :)

 $b = array(); array_unshift($a, false); while (false !== $key = next($a)) { $b[$key] = next($a); } 

Ok, (shudder) here is your one liner:

 $b = call_user_func_array('array_merge', array_map(function($v) { return array($v[0] => $v[1]); }, array_chunk($a, 2))); 
+5
source

You do not need an array, you can do it directly with the path text:

 $path = "foo/bar/hello/world"; preg_match_all("#(?J)(?<key>[^/]+)/(?<val>[^/]*)#", $path, $p); $params = array_combine($p['key'], $p['val']); print_r($params); /* Array ( [foo] => bar [hello] => world ) */ 
+3
source

I do not think that you can do better than what you have. But what about trying to put the odd and even elements into different arrays while reading the input? Then you can use array_combine to create a single-line image.

Update : array_map will not help, as it will create an array with an equal number of elements. You can do things with array_filter and array_combine , but again, this will not be shorter.

I really like what you have; short, simple, does the job. I just reorganize it into a function, say array_interleave_combine or some such.

Update 2 :

Well, you asked for it, so here it is. Trying to be too smart if you ask me. It is single-line, but I really do not think that the “purity” of this is enough to return the lost time to someone who needed to understand what was happening:

 $result = array_reduce( array('foo', 'bar', 'hello', 'world'), function($partial, $item) { static $nextKey; if ($nextKey === null) { $nextKey = $item; } else { $partial[$nextKey] = $item; $nextKey = null; } return $partial; }); 
+2
source

This solution does not need an additional array:

 $arr = array('foo', 'bar', 'hello', 'world'); for($i = 0, $count = count($arr); $i < $count; $i += 2) { $arr[$arr[$i]] = $arr[$i + 1]; unset($arr[$i], $arr[$i + 1]); } 
+1
source

Source: https://habr.com/ru/post/1342924/


All Articles