<?
$map = [];
$cur = null;
function write ($s) {
global $cur;
$cur[] = $s;
}
function set_cursor ($key) {
global $map, $cur;
$cur = [];
$map [$key] = &$cur;
}
set_cursor ("key_a");
write ("Hello");
write ("World");
set_cursor ("key_b");
write ("Foobar");
var_dump ($map);
?>
From languages I am familiar with (Javascript, C#, C) I expected $map to contain
{
"key_a": ['Hello', 'World'],
"key_b": ['Foobar']
}
Instead it contains
{
"key_a": ['Foobar'],
"key_b": ['Foobar']
}
This seems unintuitive. How do I need to modify the code to return the expected result?
As per request in the comments, here is the equivalent code in Javascript that produces the desired and expected result:
var map = {};
var cur = null;
function set_cursor (key) {
cur = [];
map [key] = cur;
}
function write (s) {
cur.push (s);
}
set_cursor ("key_a");
write ("Hello");
write ("World");
set_cursor ("key_b");
write ("Foobar");
console.log(map);
CodePudding user response:
OK I have figured it out myself in the meanwhile. In typical PHP fashion, you had to use some non-sensical arcane constructs to get it working. In particular you had to use $GLOBALS instead of global to get it to produce the same results that would be produced by any other language.
Here's the code:
<?
$map = [];
$cur = null;
function write ($s) {
global $cur;
$cur[] = $s;
}
function set_cursor ($key) {
global $map;
if (array_key_exists ($key, $map) == false)
$map[ $key] = [];
$GLOBALS["cur"] = &$map[ $key ];
}
set_cursor ("key_a");
write ("Hello");
write ("World");
set_cursor ("key_b");
write ("Foobar");
set_cursor ("key_a");
write ("Hello");
write ("Again");
set_cursor ("key_b");
write ("Bazqux");
var_dump ($map);
?>
CodePudding user response:
You could use a class to acheive this.
class Map
{
private $map = [];
private $cur = null;
public function write(string $s): self
{
$this->map[$this->cur][] = $s;
return $this;
}
public function set_cursor(string $key): self
{
$this->cur = $key;
return $this;
}
public function getMap(): array
{
return $this->map;
}
}
Usage:
$map = new Map();
$map->set_cursor("key_a");
$map->write("Hello");
$map->write("World");
$map->set_cursor("key_b");
$map->write("Foobar");
// fluent style
$map->set_cursor("key_a")
->write("Hello")
->write ("Again");
$map->set_cursor("key_b")->write("Bazqux");
// display
var_dump($map->getMap());
output
array(2) {
["key_a"]=>
array(4) {
[0]=>
string(5) "Hello"
[1]=>
string(5) "World"
[2]=>
string(5) "Hello"
[3]=>
string(5) "Again"
}
["key_b"]=>
array(2) {
[0]=>
string(6) "Foobar"
[1]=>
string(6) "Bazqux"
}
}
