While renown scientists are looking into other dimensions I'm trying to figure out how to populate multidimensional arrays with dynamic data.
I need to add an undetermined number of values that are calculated from a random function.
function my_random ($min, $max) {
$random_var = rand($min, $max);
return $random_var;
}
I would like my array to look like this:
$array_example = [
'id' => $id,
'value1' => $value1,
'value2' => $value2
];
...or maybe like this:
$array[$i] = [
'id' => $id, array(
'value1' => $value1,
'value2' => $value2
)
];
I figured a simple for-loop would do the trick and so I tried this:
for ($i = 1; $i <= $amount; $i++) {
$array[$i] = $i;
$array[$i] = [
'id' => $i, array(
'value1' => $value1,
'value2' => $value2
)
];
}
...but it comes out all wrong (from console):
string(103) "{"id":2,"value1":[14,{"1":{"id":1,"0":{"value1":[14],"value2":[11]}}},13],"value2":[11,19]}"
The for-loop seems to nest them. I tried different functions, hoping to get it right: range() to get the id and then populate it with data, array_push() and I even tried to combine and merge.
This thread makes it look simple:
$array[] = "item";
$array[$key] = "item";
array_push($array, "item", "another item");
But this solution will only work to create the index.
How do I insert those values into each index dynamically? What I ultimately need is to be able to access the array and its values like this:
$array[0]["value1"].
Thanks.
Indexed array of associative arrays
An array in PHP is actually an ordered map. A map is a type that associates values to keys. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.
The following function takes one optional integer argument, or defaults to 10, and initiates a for loop to create an indexed Array of associative array()s.
<!DOCTYPE html><html><head></head><body>
<?php
function createArrayOf( $quantity = 10 ) {
$arr = [];
for ( $i = 0; $i < $quantity; ++$i ) {
$arr[ $i ] = array(
"value_1" => "some value",
"value_2" => "another value"
);
}
return $arr;
}
?>
<pre><?php var_export( createArrayOf( 5 ) ); ?></pre>
</body></html>
Output using var_export() which:
gets structured information about the given variable. It is similar to var_dump() with one exception: the returned representation is valid PHP code.
array (
0 =>
array (
'value_1' => 'some value',
'value_2' => 'another value',
),
1 =>
array (
'value_1' => 'some value',
'value_2' => 'another value',
),
2 =>
array (
'value_1' => 'some value',
'value_2' => 'another value',
),
3 =>
array (
'value_1' => 'some value',
'value_2' => 'another value',
),
4 =>
array (
'value_1' => 'some value',
'value_2' => 'another value',
),
)
Related
I am trying to find the difference of 2 multidimensional arrays. I am attempting to solve this with a modified recursive array difference function.
If I have the following array setup:
$array1 = array(
0 => array(
'Age' => '1004',
'Name' => 'Jack'
),
1 => array (
'Age' => '1005',
'Name' => 'John'
)
);
$array2 = array(
0 => array(
'Age_In_Days' => '1004',
'Name' => 'Jack'
),
1=> array(
'Transaction_Reference' => '1005',
'Name' => 'Jack'
)
);
I am trying to match the arrays however the keys are not the same. I want to return the difference between the two multidimensional arrays where
$array1[$i]['Age'] == $array2[$i]['Age_In_Days'];
I want to keep the original array structure if the above condition holds true so the output I am looking for is:
$diff = array (1 => array (
'Age' => '1005',
'Name' => 'John'
));
However I am having issues with how to modify the recursive function to achieve this. Any help is appreciated! Thanks!
You need to loop through first array and compare values with second array. Then follows your condition. If condition is true then push this unique value to third array. Values in third array are now diff between first and second array.
$diff = [];
foreach ($array1 as $value1) {
foreach ($array2 as $value2) {
if ($value1['Age'] !== $value2['Age_In_Days']) {
array_push($diff, $value1);
}
}
}
I use this function to display any kind of multi-dimensional array as a human readeable html table. For exemple, this array :
$arr = array
(
'root' => array(
'main' => array (
'members' => array(
array ('identifier' => '36', 'fullname' => 'jonathan carter'),
array ('identifier' => '42', 'fullname' => 'hello world')
)
)
)
);
becomes a table (with echo array2table($arr, true)) :
My problem, as you can see, is that there are too many table headers when multiple arrays contains only one sub array. This is what I would like to have :
You probably say: "What did you tried ?"
Well, before displaying the table header, I made and call a recursive function which returns an array of keys if there nested tables :
function nextTableHeaders($array)
{
// requires an array with only 1 child
if (!is_array($array) || count($array) !== 1)
return array();
$key = key($array);
return array_merge(array($key), nextTableHeaders($array[$key]));
}
In that case, it returns :
array('root', 'main', 'members');
Then I join the values with ' > ' and it becomes my new table headers. But I need then to go deeper into the arrays (because I don't wan't to display "main > members", and "members"). But I didn't succeed.
I would appreciate any help.
My suggestion is to keep the table printing as is, and to create a new function that will take the array and then convert it into the sort of array which when printed will display what you wish to be displayed.
function compressArray($array) {
// Non-arrays and multiple-key arrays are unaffected
if (!is_array($array) or count($array) !== 1)
return $array;
// This is a recursive algorithm
$child = compressArray(current($array));
// Compression unnecessary when child is non-array or a multiple-key array
if (!is_array($child) or count($child) !== 1)
return $array;
// Both parent and child are single key arrays so compress
$new_key = key($array) . " > " . key($child);
return array($new_key => current($child));
}
This will convert
$arr = array
(
'root' => array(
'main' => array (
'members' => array(
array ('identifier' => '36', 'fullname' => 'jonathan carter'),
array ('identifier' => '42', 'fullname' => 'hello world')
)
)
)
);
into
$arr = array
(
'root > main > members' => array(
array ('identifier' => '36', 'fullname' => 'jonathan carter'),
array ('identifier' => '42', 'fullname' => 'hello world')
)
);
What I'd like to do is have a function that accepts two arguments, both arrays, the first being a one-dimensional array of varying lengths and the second is a multi-dimensional array of varying depths and lengths. The first array is never associative, the second is always a fully associative array.
This function would return the requested value from the multi-dimensional array as indicated by the first array.
Assume that the first array will always be hand-written and passed to this function. Meaning the developer always knows there is a value to be returned from the multi-dimensional array and would never pass a request to the function where a value did not exist.
I think the code below is the best example at what I'm trying to achieve.
//Example multi-dimensional array
$multi = array(
'fruit' => array(
'red' => array(
'strawberries' => '$2.99/lb',
'apples' => '$1.99/lb'
),
'green' => array(
'honeydew' => '$3.39/lb',
'limes' => '$0.75/lb'
)
),
'vegetables' => array(
'yellow' => array(
'squash' => '$1.29/lb',
'bellpepper' => '$0.99/lb'
),
'purple' => array(
'eggplant' => '$2.39/lb'
)
),
'weeklypromo' => '15% off',
'subscribers' => array(
'user1#email.com' => 'User 1',
'user2#email.com' => 'User 2',
'user3#email.com' => 'User 3',
'user4#email.com' => 'User 4'
)
);
//Example one-dimensional array
$single = array('fruit', 'red', 'apples');
function magicfunc($single, $multi) {
//some magic here that looks something like below
$magic_value = $multi[$single[0]][$single[1]][$single[2]];
return $magic_value;
}
//Examples:
print magicfunc(array('fruit', 'red', 'apples'), $multi);
Output:
$1.99/lb
print magicfunc(array('subscribers', 'user3#email.com'), $multi);
Output:
User 3
print magicfunc(array('weeklypromo'), $multi);
Output:
15% off
This returns the values as requested:
function magicfunc($single, $multi) {
while (true) {
if (!$single) {
break;
}
$searchIndex = array_shift($single);
foreach ($multi as $k => $val) {
if ($k == $searchIndex) {
$multi = $val;
continue 2;
}
}
}
return $multi;
}
I'm trying to insert a PHP array into a mysql database, but am having trouble with this particular array. I'm trying to create a function that takes
array( 0 => array ( 'col1' => 'value', 'col2' => 'value', 'col3' => 'value', 'col4' => value', 'col5' => 'value', 'col6' => array ( 'string' => array ( 'col7' => 'value' , 'col8' => 'value'), ), ),
1 => array ( 'col1' => 'value', 'col2' => 'value', 'col3' => 'value', 'col4' => array ( ), 'col5' => 'value', 'col6' => array ( 'string' => array ( ), ), ),
2 => array ( 'col1' => 'value', 'col2' => 'value', 'col3' => 'value', 'col4' => array ( ), 'col5' => 'value', 'col6' => array ( 'string' => array ( ), ), ), )
and seperates each numbered array and formats it as:
array( 'col1' => 'value', 'col2' => 'value', 'col3' => 'value', 'col4' => 'value', 'col5' => 'value', ['col6' => 'value','col7' => 'value',] )
array( 'col1' => 'value', 'col2' => 'value', 'col3' => 'value', 'col4' => 'value', 'col5' => 'value', ['col6' => 'value','col7' => 'value',] )
array( 'col1' => 'value', 'col2' => 'value', 'col3' => 'value', 'col4' => 'value', 'col5' => 'value', ['col6' => 'value','col7' => 'value',] )
depending on how many rows there are. Keep in mind these conditions:
+8 cols is just an example, the range can fluctuate greatly.
+Cols containing a array must be non existent if it empty, like in [1] and [2], but not [0].
+Any column could contain a empty or full array. if it contains a full array, it needs to be flatten while retaining it's value.
+Some arrays might have greater then 2 nested arrays. (elements)
+Not all of the arrays have nested arrays, they are already formatted correctly. These arrays can not be affected by the PHP function i'm trying to create.
I'm stumped, every function I've created has failed. Thanks everyone in advance.
UPDATE I used Var_export with this function to get the array above.
function flatten($array, $preserve_keys = false)
{
if (!$preserve_keys) {
$array = array_values($array);
}
$flattened_array = array();
foreach ($array as $k => $v) {
$flattened_array[$k] = $v;
if (is_array($v)) {
$flattened_array = array_merge($flattened_array, call_user_func(__FUNCTION__, $v, $preserve_keys));
} elseif ($preserve_keys) {
$flattened_array[$k] = $v;
} else {
$flattened_array[] = $v;
}
}
return (array)$flattened_array;
}
What you need is what's called a recursive function (see this question for more info: What is a RECURSIVE Function in PHP?).
Also it seems that each "col" in the array is a string (and not a number).
What you might want to try is check whether the first (or any) key in the array is numeric.
The code would look something like this:
public function extractArray($myArray){
$extractedArray = array(); // create a new array where all the flattened data will go
$arrayKeys = array_keys($myArray); // grab all the keys from the array
if (is_numeric($arrayKeys[0])): // if the first key is a number (it's nested)
$extractedArray = $myArray[0]; // remove one level of the array by grabbing everything from the first element
extractArray($extractedArray); // run our function again to check if we need to remove another layer
else:
$extractedArray = $myArray; // seems like there are no layers that need to be removed
endif;
return $extractedArray;
}
Edit:
Here is a possible solution for the second part of the problem (extracting values from possible sub-arrays)
Here are the steps we are going to take:
1) Loop through each element in our $extractedArray (from part 1) and see if it is a sub array
2) If it is an array we extract it's contents and place it in a temporary variable (an array for now)
3) We then call ourselves again (recursively) passing it the new temporary variable (until there are no more sub-arrrays left
4) Once we have extracted all the values and flattened them in to a single array, we can then loop through that array and store them as a string (or whatever else we like)
Updated Code
Here is the code:
public function flattenArrayValues($extractedArray){
$extractedValues = array();
foreach($extractedArray as $key => $eA):
if(is_array($eA)): // check whether current element is an array
reset($eA); // go to the first element of the array and grab it
$first_key = key($eA); // ...
$extractedValues[$key] = $eA[$first_key]; // this allows us to preserve the "cols" for each element
flattenArrayValues($extractedValues); //call ourselves again to check whether there are any sub-arrays
endif;
endforeach;
return $extractedValues; // seems like we extracted all the values and flattened them
// if we want we can loop through this new array and build a string out of it etc.
}
Hope this was helpful
I have simple array
array(
array( 'id'=>5, 'something' => 2, 'dsadsa' => 'fsfsd )
array( 'id'=>20, 'something' => 2, 'dsadsa' => 'fsfsd )
array( 'id'=>30, 'something' => 2, 'dsadsa' => 'fsfsd )
)
How to create associative array by id field (or something else) from it in the right way?
array(
'5' => array( 'something' => 2, 'dsadsa' => 'fsfsd )
'20' => array( 'something' => 2, 'dsadsa' => 'fsfsd )
'30' => array( 'something' => 2, 'dsadsa' => 'fsfsd )
)
Something along these lines.
$new_array = array();
foreach ($original_array as &$slice)
{
$id = (string) $slice['id'];
unset($slice['id']);
$new_array[$id] = $slice;
}
#NikitaKuhta, nope. There is no slice function which returns a column of values in a 2D keyed table associated with a given key or column heading. You can use some of the callback array_... functions, but you will still need to execute a custom function per element so its just not worth it. I don't like Core Xii's solution as this corrupts the original array as a side effect. I suggest that you don't use references here:
$new_array = array();
foreach ($original_array as $slice) {
$id = (string) $slice['id'];
unset($slice['id']);
$new_array[$id] = $slice;
}
# And now you don't need the missing unset( $slice)