Michael G Schwern wrote: > On Tue, Jan 28, 2003 at 12:11:18PM +1300, [EMAIL PROTECTED] wrote: > > > Has anyone considered removing with the syntactic distinction > > between numeric and string indexing -- that is, between array and > > hash lookup? > > PHP works this way.
Well, for some definition of "work", anyway. > http://www.php.net/manual/en/language.types.array.php > > So that makes a nice case study to investigate. The manual is strangely quiet on how this duality fits together, but through using PHP I've managed to work some of it out. Basically in PHP there are just hashes, but hashes retain the order in which elements are stored. When iterating with C<foreach> or C<print_r> you get elements back in the order you put them in: $colour = array('grass' => 'green', 'sky' => 'blue', 'orange' => 'orange'); print_r($colour); # output: Array ( [grass] => green [sky] => blue [orange] => orange ) If you add an element that doesn't have a key, then PHP finds the maximum key that looks like a non-negative integer, adds one to it, and uses that as the key for the new element, or uses zero if no elements have such keys. This means that if you never assign any explicit keys you can make it seem like the hash is a 'normal' array: $colour = array('purple', 'black', 'silver'); print_r($colour); Array ( [0] => purple [1] => black [2] => silver ) But it isn't. Remember that elements retain the order in which they were stored. So if you set them not in numerical order then they remain in that order: $colour = array(); $colour[1] = 'taupe'; $colour[3] = 'red'; $colour[0] = 'zephyr'; $colour[2] = 'pink'; print_r($colour); Array ( [1] => taupe [3] => red [0] => zephyr [2] => pink ) And if you remove an element from the middle of an array, the existing elements keep their previous indices, so the indices are no longer consecutive: $colour = array('purple', 'black', 'silver', 'gold'); unset($colour[2]); print_r($colour); Array ( [0] => purple [1] => black [3] => gold ) And if you put that element back, well it doesn't go there but appears at the end: $colour = array('purple', 'black', 'silver', 'gold'); unset($colour[2]); $colour[2] = 'bronze'; print_r($colour); Array ( [0] => purple [1] => black [3] => gold [2] => bronze ) The ordering means that it's possible to shift elements off the beginning of a hash, which is fine: $colour = array('grass' => 'green', 'sky' => 'blue', 'orange' => 'orange'); array_shift($colour); print_r($colour); Array ( [sky] => blue [orange] => orange ) There's also something in there which checks for non-negative integer keys, and if so renumbers them after shifting. This helps keep up the pretence that the hash can be used as an array: $colour = array('purple', 'black', 'silver', 'gold'); array_shift($colour); print_r($colour); Array ( [0] => black [1] => silver [2] => gold ) But this can have surprising consequences if you are trying to associate numbers with particular elements: $days = array(1 => 'day', 7 => 'week', 14 => 'fortnight', 365 => 'year'); array_shift($days); print_r($days); Array ( [0] => week [1] => fortnight [2] => year ) Zero days in a week? And the same thing happens even if the keys are quoted, so that they are strings that happen to look like integers but not actual integers: $days = array('1' => 'day', '7' => 'week', '14' => 'fortnight', '365' => 'year'); Trying that on a hash where some of the keys happen to look like integers and some don't results in the former being renumbered and the latter being left alone. Is that enough? The amazing thing is that most of the time, despite the above, what PHP calls arrays do actually work well enough. But really PHP has hashes with elements that retain their storage order plus some awkward hacks that may make them seem more like arrays in certain circumstances. It's messy. It's bordering on evil. And I've never found it to have any advantage over the Perl way of allowing the programmer to specify which data structure is required rather than making the interpreter guess. I cannot think of a worse example for Perl to follow. Smylers