php - Is array_slice safe to use on associative arrays - php

Associative array elements are implicitly ordered.
As far as I know regarding their analogue in JS (objects) there are no guarantees about the element order.
array_slice is a function dependent on the elements order.
Is it safe to assume that the result of array_slice will be consistent with the order an associative array will be iterated in using a foreach statement ?

PHP's arrays and Javascript's objects are not comparable.
PHP's arrays are ordered, associative data structures. Javascript doesn't have any equivalent to that.* PHP's arrays aren't implicitly ordered, they're explicitly ordered. That applies to both numeric and string keys.
Yes, array_slice is safe to use on them. Note that it has an explicit $preserve_keys parameter which you must set to true if you want to keep your arrays associative; otherwise they will be re-indexed numerically.
* Javascript only has fundamentally unordered, associative objects. Recent ECMAScript versions specify some ordering for them, but it's not really controllable by the user. Javascript's Array adds a usage pattern on top of those unordered objects which lets you have ordered, but non-associative data structures.

Related

How to sort an array of objects by object field in PHP?

I have an array of rows from MySQL query. What I need to do is sort them by one of the fields (unsigned int type). I looked through reference, but did not understand how exactly do I sort arrays of objects, because PHP does not seem to have something like operator overloading (what you do in C++), and some existing functions say they're unstable, meaning that with 2 equal elements their position in sorted array is undefined, which sounds really weird IMO.
So, what's the general approach in PHP when you need to sort an array of objects?
You'll need to write your own function to do the comparison. Once you have that function, you can then use usort - http://php.net/manual/en/function.usort.php
Note that this also works with sorting an array of objects, you just have to change your comparison function.

PHP - Difference of 20 between elements of an array without using nested loops

I am required to find a difference of 20 between elements of an array without using nested loops. If statements are fine. The difference must be checked between all elements not just the ones next to each other.
example of an array:
$array =array (5,2,25,1,2,21);
(i can choose my own array)
Use array_diff
Little note- while you won't be doing nested loops, if you do an array_diff in a loop technically you're nesting loops. The underlying logic of array_diff will require at least one loop internally. ( I don't know how many it truly does, but it has to iterate in order to even begin to compare the individual values. ) Why, specifically, are you not using nested loops?

Understanding PHP Arrays from a Python background

I typically code in Python, Java, or C. I'm taking on a project in PHP and I'm reading up on arrays in PHP and I'm utterly baffled. If I am understanding correctly, the numerical indices in PHP don't necessarily correspond to position and are just keys like in a dict in Python. So, when you shuffle a PHP array, the order of the elements will change, but their keys will remain the same. So when calling array[9], you might actually be getting the first element of the array if the shuffle ordered the elements that way. This raises a bunch of questions:
Is a PHP array, then, always just some kind of ordered hash table?
And what does that mean for overhead? In Python, lists function like
a classic array data structure and dictionaries more along the lines
of a hash structure. PHP seems to combine the two by assigning unique
keys to every value AND keeping track of the order of those values. If I want to use an associative array structure for constant time lookup, am I in a far worse off position than I would be with a Python dictionary because of this ordering overhead? Are there PHP data structures that are ONLY arrays or ONLY hash tables?
What happens when you remove a value from a numbered PHP array? If I
have an array, [1, 2, 3, 4, 5], I remove 4 from the array, and then
try to access array[3], is it going to give me an error, since I
removed the element with the key 3? Or does PHP do some kind of key
adjusting in such a case?
If you change the ordering of an array (i.e., through a sort or a
shuffle), is the only way to have the indices correspond to the
position to copy the array to a new array using array_values().
http://php.net/manual/en/class.splfixedarray.php
This code:
$arr = array(0,1,2,3,4);
unset($arr[3]);
echo $arr[3]; // undefined index warning, execution continues;
echo isset($arr[3]) ? $arr[3] : '';
print_r($arr);
The print_r() outputs:
Array
(
[0] => 0
[1] => 1
[2] => 2
[4] => 4
)
This depends on the function you choose. Some maintain index association, some do not.
Protip:
Never expect two seemingly-similar PHP functions to behave anything like each other. It's the "English" of programming languages: full of crap stolen from other languages and loads of conventions that contradict each other, but everyone speaks it so hop on board the freedom train.
'murca.

Accessing array better via numeric or associative key?

I iterate over an array of arrays and access the array's value through associative keys, this is a code snippet. Note: i never iterate over the total array but only with a window of 10.
//extract array from a db table (not real code)
$array = $query->executeAndFetchAssociative;
$window_start = 0;
for($i = $window_start; $i<count($array) && $i<$window_start+10; $i++)
echo($entry["db_field"]);
This is a sort of paginator for a web interface. I receive the windows_start value and display hte next 10 values.
A conceptual execution:
Receive the windows_start number
Start the cycle entering the window_start-TH array of the outer array
Display the value of a field of the inner array via associative index
Move to window_start+1
The inner arrays have about 40 fields. The outer array can grow a lot as it rapresent a database table.
Now i see that as the outer array gets bigger the execution over the windows of 10 takes more and more time.
I need some "performance theory" on my code:
If I enter the values of inner arrays via numeric key can I have better performance? In general is quickier accessing the array values with numeric index than accessing with associative index (a string)?
How does it cost entering a random entry ($array[random_num]) of an array of length N ? O(N), O(N/2) just for example
Finally the speed of iterating over an array depends on the array lenght? I mean i always iterate on 10 elements of the array, but how does the array lenght impact on my fixed length iteration?
Thanks
Alberto
If I enter the values of inner arrays via numeric key can I have
better performance? In general is quicker accessing the array values
with numeric index than accessing with associative index (a string)?
There might be a theoretical speed difference for integer-based vs string-based access (it depends on what the hash function for integer values does vs the one for string values, I have not read the PHP source to get a definite answer), but it's certainly going to be negligible.
How does it cost entering a random entry ($array[random_num]) of an
array of length N ? O(N), O(N/2) just for example
Arrays in PHP are implemented through hash tables, which means that insertion is amortized O(1) -- almost all insertions are O(1), but a few may be O(n). By the way, O(n) and O(n/2) are the same thing; you might want to revisit a text on algorithmic complexity.
Finally the speed of iterating over an array depends on the array
length? I mean i always iterate on 10 elements of the array, but how
does the array length impact on my fixed length iteration?
No, array length is not a factor.
The performance drops not because of how you access your array but because of the fact that you seem to be loading all of the records from your database just to process 10 of them.
You should move the paging logic to the database itself by including an offset and a limit in your SQL query.
Premature optimization is the root of all evil. Additional numeric and associative arrays have a very different semantic meaning and are therefore usually not interchangeable. And last but not least: No. Arrays in PHP are implemented as Hashmaps and accessing them by key is always O(1)
In your case (pagination) it's much more usefull to only fetch the items you want to display instead of fetching all and slicing them later. SQL has the LIMIT 10 OFFSET 20-syntax for that.

What are the Practical Differences Between "associate" and "indexed" Arrays in PHP?

The PHP array type is actually more akin to an an ordered map than a traditional C array. It's PHP's original general use data structure. The manual goes as far to say The indexed and associative array types are the same type in PHP, which can both contain integer and string indices.
However, there's a lot of cases where built-in language features will make a distinction between "indexed" arrays (arrays with sequential, integer keys) and "associative" arrays (arrays with non-sequential and/or keys of mixed types).
One example of this is the array_merge function.
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
If only one array is given and the array is numerically indexed, the keys get reindexed in a continuous way.
What are the other places in PHP where a distinction is made between indexed and associative arrays? I'm specifically interested in the Userland differences, although any insight into the Array implementation in PHP's source would be interesting as well.
Actually, any array, no matter if it's indexed or associative, is a hashtable (plus a doubly-linked list for maintaining the order of elements) in PHP. However, in userland PHP code, indexed and associative arrays almost always serve different purposes and sometimes need to be treated in different ways, so several functions like sort/asort make a distinction between them just for convenience.
The most prevalent one that comes to mind is that an indexed array can be looped over using a traditional for loop, whereas an associative one cannot (because it does not have the numeric indexes):
for ($i = 0; $i < count($indexed_array); $i++)
{
// do something with $indexed_array[$i]
}
Of course, php also has a foreach keyword, which works the same on both types.
.. and then there is SplFixedArray, starting from 5.3, it supports only integer indexes, has fixed size and is generally faster than the native arrays.
One interesting difference I've found is when using json_encode.
json_encode(array(0=>0,1=>1,2=>2));
> [0,1,2]
json_encode(array(0=>0,2=>2));
> {"0":0,"2":2}
As a lone example this makes sense, but it's more surprising when combined with, say, array_filter.
$f = function($x) { return $x != 1; };
json_encode(array_filter(array(0,1,2), $f));
> {"0":0,"2":2}
We started off with a numeric array, filtered some elements out, but the resulting json is an associative array!
Note that we can get the desired json by using array_values.
json_encode(array_values(array_filter(array(0,1,2),$f)));
> [0,2]
Pretty much all of the core sorting functions (with all the sort, ksort, asort variations depending on whether you want to maintain key association and so on).

Categories