Execute same logic for multiple multidimensional arrays - php

I'm currently trying the following:
I have multiple arrays defined. They all are filled by fetching data from the database, so they all contain the same columns/data structure, but with different data. For example, lets say the arrays are different schools, so there is:
//pseudoCode:
array1 = ({"Name: Peter", "Surname: not peter"},{"Name: doe", "Surname: john"});
array2 = ({"Name: asfwe", "Surname: qwfqwf"},{"Name: asfas", "Surname: fsbng"});
array3 = ({"Name: weqw", "Surname: wqeqewqw"},{"Name: doqweqwee", "Surname: wewe"});
Now, for all these arrays, I want to do the same things. In my case, I have multiple if else cases, checking the length of the array and doing some stuff.
So far I'm only doing it for array 1 though. Now my first idea was to simply copy the logic and refactor all variable names to array2 respectively to array3, but this wouldn't make sense, because in my real case, its 10 arrays instead of 3 and the logic is about 150 lines of code, so I would have a lot of duplicate code and would need to change it everywhere, if something in the logic changes.
Now the question is: How can I do the same procedure for every array?
So what I would need is something like:
//pseudoCode again
foreach(array in array1, array2, array3, array4, array5,....){
//do something with variable "array", which is actually one of the defined arrays
}
A hint in the right direction would be great.
Thank you in advance.

Procedure code demand exporting logic to function:
function foo($array) {
// modify the array or do what ever you need
return $array; // in case it has been modify
}
Now can you function as:
foreach($arrays as &$arr)
$arr = foo($arr); // calling the function on each array
// the re-assign is just in case it has been modify
In this example $arrays stand for array with all your inner arrays as:
$arrays = array($array1, $array2, $array3, ...)
if your array as getting dynamicly from some other function / SQL code do:
$arrays = []; // init empty array
while (#SOME_CONDITION#) {
$arrays[] = getAnotherArrayFunction(); // append the array to your array
}

Related

Remove element from associative array in PHP

I need to remove a element from an associative array with an string structure.
Example:
$array = array(
"one"=>array("Hello", "world"),
"two"=>"Hi"
)
I want to create a function that removes the elements like this:
function removeElement($p) {
// With the information provided in $p something like this should happen
// unset($array["one"]["hello"])
}
removeElement("one.hello");
Your base array is associative, the inner array (key one) is not, its a indexed array, which you can not access via ["hello"] but rather [0].
You can remove the hello value by using the unset function, but the indexes will stay as they are:
$array = ['Hello', 'World']; // array(0: Hello, 1: World)
unset($array[0]); // Array is now array(1: World)
If you wish to keep unset and keep the array indexes in order, you can fetch the values using the array_values function after unset:
unset($array[0]);
$array = array_values($array); // array(0: World)
Or you could use array_splice.
When it comes to using a string as key for multidimensional array with a dot-separator I'd recommend taking a look at laravels Arr::forget method which does pretty much exactly what you are asking about.
This would be a static solution to your question, in any case, you need to use explode.
function removeElement($p, $array) {
$_p = explode('.', $p);
return unset($array[$_p[0]][$_p[1]]);
}
But bear in mind, this doesn't work if you have more in $p (like: foo.bar.quux)

Transfer keys from a 2D array to fill a 1D array

PHP has plenty of useful functions and Im wondering if Im overlooking one that has already been built.
Lets say you have an array such as:
$first_array = array("Name"=>"Angela", "Age"=>24);
and you wanted to grab the keys from the first array to create a second array (which could then be pushed into a third array). So you need to create:
$second_array = array("Name", "Age");
Is there a way to achieve this result without this loop?:
foreach($first_array as $k=>$v){
array_push($second_array, $k);
}
This should do it:
array_keys($first_array);
Use array_keys($first_array) to get the array of all the keys in the $first_array

Referencing Arrays in PHP - Questions

I am trying to understand the following code in PHP. Here is the overview,
There are 2 arrays, which consists of key values pairs in the form, $k => $v
These 2 arrays are merged together using array_merge function to form the third array.
Now, this array is passed to a function. Only one argument, the array name is passed.
Here is the code (please note that this code is only a concept, not the real code):
<?php
function test(&$myArray, 0)
{
reset($myArray);
foreach ($myArray as $k => $v)
{
....
}
}
$arr3 = array_merge((array) $arr1, (array) $arr2);
test($arr3)
}
Questions:
The function is defined in such a way, that it expects two arguments, however we are passing only one argument. Is it because the second argument is always 0 as initialized in the function prototype? So, there is no need to pass the same number of arguments?
Here the array name is passed. My guess is that, it will pass a pointer to the first element of the array (base address of the array in memory) to the function.
In this case, if you look at the prototype, the array name is preceded with an ampersand. So, this means, a reference to the array, the address?
Why is it necessary to call the reset function on the array. Is it because the array_merge function which was used to form this array was called before the test function? So, it moved the pointer in the array ahead of the first element as a result of merging $arr1 and $arr2?
There is no value returned in the function, test. So, does it modify the value of the original array in the memory itself, and hence there is no need to return an array?
Thanks.
<?php
function test($myArray,$a =0) //passing by value
{
reset($myArray);
return $myArray;
}
$arr3 = test($arr3); //call n store it back it in $arr3
function test(&$myArray,$a =0) //passing by reference
{
reset($myArray);
}
test($arr3); //just call;
?>

Autofill array with empty data to match another array size

I have 2 sets of arrays:
$dates1 = array('9/12','9/13','9/14','9/15','9/16','9/17');
$data1 = array('5','3','7','7','22','18');
// for this dataset, the value on 9/12 is 5
$dates2 = array('9/14','9/15');
$data2 = array('12','1');
As you can see the 2nd dataset has fewer dates, so I need to "autofill" the reset of the array to match the largest dataset.
$dates2 = array('9/12','9/13','9/14','9/15','9/16','9/17');
$data2 = array('','','12','1','','');
There will be more than 2 datasets, so I would have to find the largest dataset, and run a function for each smaller dataset to properly format it.
The function I'd create is the problem for me. Not even sure where to start at this point. Also, I can format the date and data arrays differently (multidimensional arrays?) if for some reason that is better.
You can do this in a pretty straightforward manner using some array functions. Try something like this:
//make an empty array matching your maximum-sized data set
$empty = array_fill_keys($dates1,'');
//for each array you wish to pad, do this:
//make key/value array
$new = array_combine($dates2,$data2);
//merge, overwriting empty keys with data values
$new = array_merge($empty,$new);
//if you want just the data values again
$data2 = array_values($new);
print_r($data2);
It would be pretty easy to turn that into a function or put it into a for loop to operate on your array sets. Turning them into associative arrays of key/value pairs would make them easier to work with too I would think.
If datas are related will be painful to scatter them on several array.
The best solution would be model an object with obvious property names
and use it with related accessor.
From your question I haven't a lot of hint of what data are and then I have to guess a bit:
I pretend you need to keep a daily log on access on a website with downloads. Instead of using dates/data1/data2 array I would model a data structure similar to this:
$log = array(
array('date'=>'2011-09-12','accessCount'=>7,'downloadCount'=>3),
array('date'=>'2011-09-13','accessCount'=>9), /* better downloadsCount=>0 though */
array('date'=>'2011-09-15','accessCount'=>7,'downloadCount'=>3)
...
)
Using this data structure I would model a dayCollection class with methods add,remove,get,set, search with all methods returning a day instance (yes, the remove too) and according signature. The day Class would have the standard getter/setter for every property (you can resolve to magic methods).
Depending on the amount of data you have to manipulate you can opt to maintain into the collection just the object data (serialize on store/unserialize on retrieve) or the whole object.
It is difficult to show you some code as the question is lacking of details on your data model.
If you still want to pad your array than this code would be a good start:
$temp = array($dates, $data1, $data2);
$max = max(array_map('count',$temp));
$result = array_map( function($x) use($max) {
return array_pad($x,$max,0);
}, $temp);
in $result you have your padded arrays. if you want to substitute your arrays do a simple
list($dates, $data1, $data2) = array_map(....
You should use hashmaps instead of arrays to associate each date to a data.
Then, find the largest one, cycle through its keys with a foreach, and test the existence of the same key in the small one.
If it doesn't exist, create it with an empty value.
EDIT with code (for completeness, other answers seem definitely better):
$dates_data1 = array('9/12'=>'5', '9/13'=>'3', '9/14'=>'7' /* continued */);
$dates_data2 = array('9/14'=>'12', '9/15'=>'1');
#cycle through each key (date) of the longest array
foreach($dates_data1 as $key => $value){
#check if the key exists in the smallest and add '' value if it does not
if(!isset( $date_data2[$key] )){ $date_data2[$key]=''; }
}

PHP - Variable Variables & array_merge() - not working

I have a bunch of arrays, which are stored in different variables like $required, $reserved, etc...
I would like to allow (inside a function) an array of options to be passed (like $options = array('required', 'reserved')), and that array would then be used to define which arrays to merge together and return at the end of the function.
So, I have this code in part of the function, that should grab all the options and merge the arrays, using variable variables to get the arrays from the strings passed in the options array):
$array = array();
foreach ($options as $key) {
$array_to_merge = ${$key};
array_merge($array, $array_to_merge);
}
return $array;
However, when I return the $array, it shows 0 items. If I print_r($array_to_merge);, I actually get the entire array as I should.
Does array_merge() simply not work with variable variables, or am I missing something here...?
array_merge returns the merged array, you're not assigning that return value to anything and thus it is being lost.
$array = array_merge($array, $array_to_merge);
should fix your problem.
If I read it right you can also simplify your code (replaces the loop) to just:
$array = call_user_func_array("array_merge", compact($options));
compact replaces the variable variable lookup and gets the list of arrays. And in effect there is only one array_merge call necessary.

Categories