divide an array into many arrays using a given key in php - php

I have an array like
array (
(1) => array => ([1]=aa, [2]=other keys and values),
(2) => array => ([1]=bb, [2]=other keys and values),
(3) => array => ([1]=cc, [2]=other keys and values),
(4) => array => ([1]=aa, [2]=other keys and values),
(5) => array => ([1]=bb, [2]=other keys and values),
(6) => array => ([1]=cc, [2]=other keys and values),
(7) => array => ([1]=bb, [2]=other keys and values)
)
I would like to make arrays based on [1] = aa/bb/cc/dd.
To divide the original array in to various unique arrays which have same value of [1] key.
I do not want to use foreach as the result set is expected to reach 10k rows.
Is this optimal at all??

No matter what solution you choose, you will have to loop over all of the rows in your array, no matter what. Either directly or indirectly. There is no magic code that can decide what's inside a sealed box without opening the box.
So, apart from the obvious foreach you can use array_walk

Is this optimal at all??
Definitely not.
Though it is not foreach to blame but a programmer who have 10k rows to loop over.
If it's regular web-page served on user's request, there shouldn't be 10k rows by any means. You have to reduce the number at least by factor of 100. Or let the data storage to do the necessary calculations.

Related

PHP merge Arrays?

I have 2 arrays, I need to merge them into a single but using array_merge values ​​fray and the final array incorrect. I try $array1+$array2, but the same thing happens.
And at the moment I have no idea how to fix it.
UPDATE: in my case array_merge and array_merge_recursive return the same result (data from the last of the array overwrites the rest)
UPDATE2: my fail for those arrays work well, I applied to other. Thanks problem solved (after Stijn I realized that it is better to merge arrays first and then apply my transformation)
Array
(
[0] => Array
(
[DOC_DATE] => 20.09.13
[LINK] => �������
[QUERY_ID] =>
[DOC] => 35428
[DOC_TYPE] =>
)
[1] => Array
(
[DOC_DATE] => 20.09.13
[LINK] => �������
[QUERY_ID] =>
[DOC] => 35428
[DOC_TYPE] =>
)
You'll want array_merge_recursive instead.
array_merge_recursive() merges the elements of one or more arrays together so that the values of one are appended to the end of the
previous one. It returns the resulting array.
If the input arrays have the same string keys, then the values for
these keys are merged together into an array, and this is done
recursively, so that if one of the values is an array itself, the
function will merge it with a corresponding entry in another array
too. If, however, the arrays have the same numeric key, the later
value will not overwrite the original value, but will be appended.
I think you are looking for array_merge_recursive
Just use array_merge_recursive($array1, $array2)

Why does the sort order of multidimensional child arrays revert as soon as foreach loop used for sorting ends?

I have a very strange array sorting related problem in PHP that is driving me completely crazy. I have googled for hours, and still NOTHING indicates that other people have this problem, or that this should happen to begin with, so a solution to this mystery would be GREATLY appreciated!
To describe the problem/question in as few words as possible: When sorting an array based on values inside a multiple levels deeply nested array, using a foreach loop, the resulting array sort order reverts as soon as execution leaves the loop, even though it works fine inside the loop. Why is this, and how do I work around it?
Here is sample code for my problem, which should hopefully be a little more clear than the sentence above:
$top_level_array = array('key_1' => array('sub_array' => array('sub_sub_array_1' => array(1),
'sub_sub_array_2' => array(3),
'sub_sub_array_3' => array(2)
)
)
);
function mycmp($arr_1, $arr_2)
{
if ($arr_1[0] == $arr_2[0])
{
return 0;
}
return ($arr_1[0] < $arr_2[0]) ? -1 : 1;
}
foreach($top_level_array as $current_top_level_member)
{
//This loop will only have one iteration, but never mind that...
print("Inside loop before sort operation:\n\n");
print_r($current_top_level_member['sub_array']);
uasort($current_top_level_member['sub_array'], 'mycmp');
print("\nInside loop after sort operation:\n\n");
print_r($current_top_level_member['sub_array']);
}
print("\nOutside of loop (i.e. after all sort operations finished):\n\n");
print_r($top_level_array);
The output of this is as follows:
Inside loop before sort operation:
Array
(
[sub_sub_array_1] => Array
(
[0] => 1
)
[sub_sub_array_2] => Array
(
[0] => 3
)
[sub_sub_array_3] => Array
(
[0] => 2
)
)
Inside loop after sort operation:
Array
(
[sub_sub_array_1] => Array
(
[0] => 1
)
[sub_sub_array_3] => Array
(
[0] => 2
)
[sub_sub_array_2] => Array
(
[0] => 3
)
)
Outside of loop (i.e. after all sort operations finished):
Array
(
[key_1] => Array
(
[sub_array] => Array
(
[sub_sub_array_1] => Array
(
[0] => 1
)
[sub_sub_array_2] => Array
(
[0] => 3
)
[sub_sub_array_3] => Array
(
[0] => 2
)
)
)
)
As you can see, the sort order is "wrong" (i.e. not ordered by the desired value in the innermost array) before the sort operation inside the loop (as expected), then is becomes "correct" after the sort operation inside the loop (as expected).
So far so good.
But THEN, once we're outside the loop again, all of a sudden the order has reverted to its original state, as if the sort loop didn't execute at all?!?
How come this happens, and how will I ever be able to sort this array in the desired way then?
I was under the impression that neither foreach loops nor the uasort() function operated on separate instances of the items in question (but rather on references, i.e. in place), but the result above seems to indicate otherwise? And if so, how will I ever be able to perform the desired sort operation?
(and WHY doesn't anyone else than me on the entire internet seem to have this problem?)
PS.
Never mind the reason behind the design of the strange array to be sorted in this example, it is of course only a simplified PoC of a real problem in much more complex code.
Your problem is a misunderstanding of how PHP provides your "value" in the foreach construct.
foreach($top_level_array as $current_top_level_member)
The variable $current_top_level_member is a copy of the value in the array, not a reference to inside the $top_level_array. Therefore all your work happens on the copy and is discarded after the loop completes. (Actually it is in the $current_top_level_member variable, but $top_level_array never sees the changes.)
You want a reference instead:
foreach($top_level_array as $key => $value)
{
$current_top_level_member =& $top_level_array[$key];
EDIT:
You can also use the foreach by reference notation (hat tip to air4x) to avoid the extra assignment. Note that if you are working with an array of Objects, they are already passed by reference.
foreach($top_level_array as &$current_top_level_member)
To answer you question as to why PHP defaults to a copy instead of a reference, it's simply because of the rules of the language. Scalar values and arrays are assigned by value, unless the & prefix is used, and objects are always assigned by reference (as of PHP 5). And that is likely due to a general consensus that it's generally better to work with copies of everything expect objects. BUT--it is not slow like you might expect. PHP uses a lazy copy called copy on write, where it is really a read-only reference. On the first write, the copy is made.
PHP uses a lazy-copy mechanism (also called copy-on-write) that does
not actually create a copy of a variable until it is modified.
Source: http://www.thedeveloperday.com/php-lazy-copy/
You can add & before $current_top_level_member and use it as reference to the variable in the original array. Then you would be making changes to the original array.
foreach ($top_level_array as &$current_top_level_member) {

PHP comparing two (potentially differently-sized) 2D arrays

I'm trying to compare two 2D arrays in PHP and my head is hurting with all the recursion - this'll probably be obvious to someone who's used to it.
I have two 2D arrays which look like this, called $submittedArray2D and $dbArray:
{
[0] => {
[0] => 'name'
[1] => 'sectors'
[2] => 'address'
[3] => 'url'
}
[1] => {
[0] => 'name'
[1] => 'sectors'
[2] => 'address'
[3] => 'url'
}
...
}
$submittedArray2D comes from user input, while $dbArray holds what is already in the database.
I want to compare them to see if any of the values have been updated in $submittedArray2D, and save those changes to $dbArray accordingly.
I also want to pass any changed addresses to a separate function for geocoding, the results of which will be stored in another database field, where the keys reference the same entry in $dbArray (so $geocode[4] refers to $dbArray[4], for example).
I've tried out some foreach statements to go through the arrays sequentially, but this breaks down if one of the entries has been removed from the middle of the array, because the two arrays are no longer in sequence. I'm wondering whether some kind of ID for each array entry might make sense, but I'm not sure where to start.
Any ideas or pointers would be much appreciated!
I managed it in the end by storing a unique ID alongside each array element, that was it was possible to loop through and check whether that ID existed in the comparator array and then check whether the address had changed, and if so store the change (along with the ID) in a separate array for processing.

Which is more efficent PHP: array_intersect() OR array_intersect_key()

Is it more efficient to use the key intersect or the value intersect if both key and value have the same contents for example:
Array
(
[743] => 743
[744] => 744
[745] => 745
[746] => 746
[747] => 747
[748] => 748
)
Is there any difference in performance in using one or the other with the same values. Similar to the difference of using double or single quotes?
From another post: I have two unordered integer arrays, and i need to know how many integers these arrays have in common
Depending on your data (size) you
might want to use
array_intersect_key() instead of
array_intersect(). Apparently the
implementation of array_intersect
(testing php 5.3) does not use any
optimization/caching/whatsoever but
loops through the array and compares
the values one by one for each element
in array A. The hashtable lookup is
incredibly faster than that.

PHP Array Efficiency and Memory Clarification

When declaring an Array in PHP, the index's may be created out of order...I.e
Array[1] = 1
Array[19] = 2
Array[4] = 3
My question. In creating an array like this, is the length 19 with nulls in between? If I attempted to get Array[3] would it come as undefined or throw an error? Also, how does this affect memory. Would the memory of 3 index's be taken up or 19?
Also currently a developer wrote a script with 3 arrays FailedUpdates[] FailedDeletes[] FailedInserts[]
Is it more efficient to do it this way, or do it in the case of an associative array controlling several sub arrays
"Failures" array(){
["Updates"] => array(){
[0] => 12
[1] => 41
}
["Deletes"] => array(){
[0] => 122
[1] => 414
[1] => 43
}
["Inserts"] => array(){
[0] => 12
}
}
Memory effiency isn't really something you need to worry about in PHP unless you're dealing with really huge arrays / huge numbers of variables.
An array in PHP isn't really like an array in C++ or a similar lower-level language; an array in PHP is a map. You have a list of keys (which must be unique and all of type string or integer), and a list of values corresponding to the keys. So the following is a legal array:
array(0 => 'butt', 1 => 'potato', 2 => 'tulip')
but so is
array(5 => 'i', 'barry' => 6, 19 => array(-1 => array(), 7 => 'smock'))
In both cases there are 3 entries in the array, hence 3 keys and 3 values.
In addition to the keys and values in the array, one array may be distinguished from another by the order in which the key/value pairs occur. If you define an array so that it has nonnegative integers as keys, this will often be the expected order. The order matters when you use constructs like foreach().
array[3] will be undefined/unset but not causing an error, and the array will use only memory for that 3 values - php isn't like C where you have to look at those things.
Accessing $arr[3] gives a notice: Notice: Undefined offset: 3 in /data/home/sjoerd/public_html/svnreps/test/a.php on line 3. You can avoid this by checking with isset() or array_key_exists().
There are no nulls stored.
Having empty elements won't take up extra memory.
Whether you should use multiple variables or an array depends on the context and how you use the variables.

Categories