5 ms·
PHP arrays are not really arrays, they are sort of hash-maps. You can do things like $arr = array(1 => 10, "1" => 11); Or even $arr = array('他妈的我的生活
by rorrr 15y ago
PHP arrays are not really arrays, they are sort of hash-maps.
You can do things like
$arr = array(1 => 10, "1" => 11);
Or even
$arr = array('他妈的我的生活' => 5);
But at the same time you can treat them as regular zero-based arrays.
$arr = array();
$arr[] = 1;
$arr[] = 2;
$arr[] = 3;
$arr[] = 'dog';
- fhars 15y agoAnd once you relalize that they are really hashes you also realize that a fast and memory efficient representation will use at least nine machine words or 72 bytes per value: 1 + x for the pointer in the bucket array (you don't want 100% occupancy to avoid hash collisions), 2 for the cons cell of the list stored in the bucket (the second element of which will usually be NULL if you have a good hash function and low occupancy), 2 for the key-value pair pointed to by the first element of the cons cell representing the index and the value, and two each for the integer key and value plus their tag words). And you may also want to store some metadata (like the length of the list stored in each bucket) with the hash, so the PHP array in the example is within a factor of two from the naive optimum for a dynamically typed language without specialized arrays. Its just the price you have to pay for not caring about the type of your "array" keys.
- obtu 15y agoThat or specialize. Lua, Javascript, and PyPy all have more efficient storage of integer-keyed hashes. Lua's solution is particularly simple and could easily be transferred to PHP.
- lysium 15y agoIn PHP you can mix the types of the key, so that won't work.
- lysium 15y agoIn another thread, dchest points out http://news.ycombinator.com/item?id=3360369 http://news.ycombinator.com/item?id=3360369 that Lua 5.0 allows mixed-typed keys, too, so that may work.
- obtu 15y agoYes. You can specialise the implementation without breaking semantics. Lua, PyPy, and some Javascript VMs are examples of that.
- deleted 15y ago[deleted]
- deleted 15y ago[deleted]
- wotnarg 15y agoYou can mix types and specialize; HipHop does. The key is that the implementation needs to be able to switch array types on the fly and convert itself. In the common case, using a specialized array will be big wins in space and time, and in the uncommon case, it can revert to a generic version.
- birken 15y agoA PHP array is in fact just an ordered hash-map (IE.. hash map with an associated linked list which tracks the iteration order). When you do an array append, the logic PHP runs is it tries to guess what the most logical key would be, add that to the hash-map and then to the end of the linked list. $a = array(); $a[] = 'A'; $a[] = 'B'; print_r($a); Array ( [0] => A [1] => B ) $b = array(); $b[5] = 'A'; $b[100] = 'B'; $b[] = 'C'; print_r($b); Array ( [5] => A [100] => B [101] => C )
- rorrr 15y agoI think they are a little more complex than regular hash maps. 1) They keys can be integers or unicode strings (ordering works differently for these two cases) 2) The keys are not necessarily ordered (see ksort and krsort functions, for example).
- wlievens 15y agoThey are ordered by insertion. That's different from for instance objects in Javascript.
- rorrr 15y agoNot really $arr = array(); $arr[0] = 'cat'; $arr[2] = 'dog'; $arr[1] = 'fish'; krsort($arr); var_dump($arr); Outputs: array(3) { [2]=> string(3) "dog" [1]=> string(4) "fish" [0]=> string(3) "cat" }
- josegonzalez 15y agoWell you are explicitly sorting the array by keys, so its not like you are contradicting his sentence. Remove the krsort() call and your "not really" becomes "example".
- Wilya 15y agoIt's funny. I don't have much experience with php, and I had to actually run your last example to know that it appended the values (instead of recreating the array with a single value each time). Is there an append operator, or something more explicit ? '+=' seems to do something strange..
- ars 15y ago[] IS the append operator. And += only works right if both sides are arrays. If not the right side will be converted. += is really intended for hashmaps, not integer indexes, for those use [].
- sapphirecat 15y ago+= does union-by-key: any keys present in the right array, and not in the left, are appended to the left. `array_merge` will append all numeric keys from the right array to the left, under new key values, as if you used [] one-by-one; for string keys, all keys from the right are copied into the left, possibly overwriting what was there. In real code, I either have all-numeric or all-string keys, and `array_merge` does what I want in bulk operations: it's essentially equal to Python list.extend and dict.update, respectively. `+` on arrays is basically useless for me.
- MindTwister 15y agoIf you want something more explicit you probably want array_push($array,$val1,$val2,$val....);
- pacmon 15y agoNot sure exactly what you were trying. Using the [] syntax is common for appending elements (using the next available key). Otherwise you can use the array functions (array_push/pop/etc). As for plain operators, here is how PHP handles array operators: http://www.php.net/manual/en/language.operators.array.php http://www.php.net/manual/en/language.operators.array.php
- gcb 15y agoN.B. when he says at the same, it's really at the same time. $x = array(); $x['asfd']=123; $x[] = 4; var_dump($x); array(2) { ["asfd"]=> int(123) [0]=> int(4) }
- qixxiq 15y agoI think its important to note your first example actually isn't valid. Part of PHP's type-mixing means strings that consist of an integer representation as array keys are automatically casted to int. $arr = array(1 => 10, "1" => 11); echo $arr[1]; // >> 11
- dspillett 15y agoIt is the same for Javascript: even though you have an Array object that you can instantiate instead of the more generic Object, they are much the same thing under the hood with both arrays and objects being hash maps [you can use the two interchangably to an extent (if you don't need the extra functinos defined by the array prototype) - references object properies in an hash-like manner or array contents the same way as object properties]. I suspect a number of languages have simiar memory (in)efficiency with their array types because the arrays are implemented this way (and the stuff stored in each slot is untyped so you'll not just store that integer, at very least the engine will need a marker that identifies it as an integer rather than something else). The high memory use is one of the prices you pay for the type flexibility.
- cygx 15y agoIt is the same for Javascript: even though you have an Array object that you can instantiate instead of the more generic Object, they are much the same thing under the hood with both arrays and objects being hash maps While this is true if you only consider language semantics, implementions do use actual arrays to store dense properties with integer names, ie arrays are backed by both flat and sparse storage with some heuristic algorithm to determine when to use what.
- dspillett 15y agoGood point. Presumably that is one of the differences in array performance between modern browsers and their eldery relatives.