What is the best way to achieve the following? I.e. building the array keys from another array dynamically?
$array = (
'key1',
'key2',
'key3'
);
Resulting in:: $arr['key1']['key2']['key3'] = array()/value;
So in other words the more values you add to $array (and or less) then the corresponding mulitidensional array is built up.
Thanks
You could easily build a recursive function, or I use a reference:
$array = array('key1', 'key2', 'key3');
$result = array();
$temp = &$result;
foreach($array as $key) {
$temp =& $temp[$key];
}
$temp = 'value'; //or whatever
var_dump($result);
I'd already started, so I'll post my answer even though there's already an accepted answer:
$input = array('key1', 'key2', 'key3');
$result = array();
buildArray($input, $result);
print_r($result);
function buildArray($input, &$result){
if(0 == count($input))
return $result;
$next = array_shift($input);
$result[$next] = array();
buildArray($input, $result[$next]);
}
Works, though I think the answer posted by #AbraCadaver is more elegant.
Related
I'm trying to write a function that do the following :
Let's say i have an array :
$data = array(
array('10','15','20','25'),
array('Blue','Red','Green'),
array('XL','XS')
)
and my result array should be like :
$result = array(
array('10','15','20','25'),
array('Blue','Red','Green','Blue','Red','Green','Blue','Red','Green','Blue','Red','Green')
array('XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS','XL','XS')
)
Im stuck with this because i want a function that is able to do this no matter how much array there is in the first array $data
I have only been able to write this, which is what give the $result array :
foreach($data[2] as $value2){
$result[2][] = $value2;
foreach($data[1] as $value1){
$result[1][] = $value1;
foreach($data[0] as $value0){
$result[0][] = $value0;
}
}
}
After a few research, it seems that a recursive function is the way to go in order to dynamically generate those foreach but i can't get it to work.
Thanks for your help.
This is dynamic:
$result[] = array_shift($data);
foreach($data as $value) {
$result[] = call_user_func_array('array_merge',
array_fill(0, count($result[0]), $value));
}
Get and remove the first element from original
Loop remaining elements and fill result with values X number of values in first element
Since the elements were arrays merge them all into result
If modifying the original is unwanted, then use this method:
$result[] = reset($data);
while($value = next($data)) {
$result[] = call_user_func_array('array_merge',
array_fill(0, count($result[0]), $value));
}
just use array_fill and array_merge functions
$result = array(
$data[0],
array_merge(...array_fill(0,count($data[0]), $data[1])),
array_merge(...array_fill(0,count($data[0])*count($data[0]), $data[2]))
);
print_r($result);
demo on eval.in
I have been looking through stackoverflow, and I found nothing that answered my question, on how I shuffle a list without getting the associative arrays. Since my code uses shuffle_assocI get the associative arrays, but using shuffle didn't get me anywhere, so now I turn here.
function shuffle_assoc($list) {
if (!is_array($list)) return $list;
$keys = array_keys($list);
shuffle($keys);
$random = array();
foreach ($keys as $key) {
$random[] = $list[$key];
}
return $random;
}
$arr = array();
$arr[] = "test 1<br>";
$arr[] = "test 2 <br>";
$arr[] = "test 3 <br>";
$arr[] = "test 4 <br>";
print_r(shuffle_assoc($arr));
?>
This is how it looks when I run the code
However I don't want the Array ([0] => parts to show, I only want to randomly shuffle the test(1/2/3/4)list every time I run the code.
print_r function display data as they are. So it print array when you give it array. You need to implode your array into string:
echo implode('',shuffle_assoc($arr));
edit:
or just
echo implode('',shuffle($arr));
Try this:
$array = shuffle($arr);
foreach($array as $a)
{
echo $a;
}
I got stuck somehow on the following problem:
What I want to achieve is to merge the following arrays based on key :
{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}}
{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}}
{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}}
{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}}
{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}}
{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}
Which needs to output like this:
[{"item_header":"Entities"},
{"list_items" :
[{"submenu_id":"Parents","submenu_label":"parents"},
{"submenu_id":"Insurers","submenu_label":"insurers"}]
}]
[{"item_header":"Users"},
{"list_items" :
[{"submenu_id":"New roles","submenu_label":"newrole"}
{"submenu_id":"User - roles","submenu_label":"user_roles"}
{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}]
}]
[{"item_header":"Accounting"},
{"list_items" :
[{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}]
}]
I have been trying all kinds of things for the last two hours, but each attempt returned a different format as the one required and thus failed miserably. Somehow, I couldn't figure it out.
Do you have a construction in mind to get this job done?
I would be very interested to hear your approach on the matter.
Thanks.
$input = array(
'{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}}',
'{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}}',
'{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}}',
'{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}}',
'{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}}',
'{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}',
);
$input = array_map(function ($e) { return json_decode($e, true); }, $input);
$result = array();
$indexMap = array();
foreach ($input as $index => $values) {
foreach ($values as $k => $value) {
$index = isset($indexMap[$k]) ? $indexMap[$k] : $index;
if (!isset($result[$index]['item_header'])) {
$result[$index]['item_header'] = $k;
$indexMap[$k] = $index;
}
$result[$index]['list_items'][] = $value;
}
}
echo json_encode($result);
Here you are!
In this case, first I added all arrays into one array for processing.
I thought they are in same array first, but now I realize they aren't.
Just make an empty $array=[] then and then add them all in $array[]=$a1, $array[]=$a2, etc...
$array = '[{"Entities":{"submenu_id":"Parents","submenu_label":"parents"}},
{"Entities":{"submenu_id":"Insurers","submenu_label":"insurers"}},
{"Users":{"submenu_id":"New roles","submenu_label":"newrole"}},
{"Users":{"submenu_id":"User - roles","submenu_label":"user_roles"}},
{"Users":{"submenu_id":"Roles - permissions","submenu_label":"roles_permissions"}},
{"Accounting":{"submenu_id":"Input accounting data","submenu_label":"new_accounting"}}]';
$array = json_decode($array, true);
$intermediate = []; // 1st step
foreach($array as $a)
{
$keys = array_keys($a);
$key = $keys[0]; // say, "Entities" or "Users"
$intermediate[$key] []= $a[$key];
}
$result = []; // 2nd step
foreach($intermediate as $key=>$a)
{
$entry = ["item_header" => $key, "list_items" => [] ];
foreach($a as $item) $entry["list_items"] []= $item;
$result []= $entry;
}
print_r($result);
I would prefer an OO approach for that.
First an object for the list_item:
{"submenu_id":"Parents","submenu_label":"parents"}
Second an object for the item_header:
{"item_header":"Entities", "list_items" : <array of list_item> }
Last an object or an array for all:
{ "Menus: <array of item_header> }
And the according getter/setter etc.
The following code will give you the requisite array over which you can iterate to get the desired output.
$final_array = array();
foreach($array as $value) { //assuming that the original arrays are stored inside another array. You can replace the iterator over the array to an iterator over input from file
$key = /*Extract the key from the string ($value)*/
$existing_array_for_key = $final_array[$key];
if(!array_key_exists ($key , $final_array)) {
$existing_array_for_key = array();
}
$existing_array_for_key[count($existing_array_for_key)+1] = /*Extract value from the String ($value)*/
$final_array[$key] = $existing_array_for_key;
}
I have an array that stores some values. I'm trying to detect the similar values and add them to new array.
example:
$arrayA = array( 1,4,5,6,4,2,1);
$newarray = (4,1);
Any help?
Use the array_intersect() method. For example
$arrayA = array(1,4,5,6,4,2,1);
$arrayB = array(4,1);
$common_values = array_intersect($arrayA, $arrayB);
try this:
$array = array(1,4,5,6,4,2,1);
$duplicates = array_unique(array_diff_assoc($array, array_unique($array)));
$a1 = array( 1,4,5,6,4,2,1);
$a = array();
foreach($a1 as $value){
if(!in_array($value, $a)){
$a[] = $value;
}
}
$arrayA = array(1,4,5,6,4,2,1);
$newarray = array_diff_assoc($arrayA, array_unique($arrayA));
I have $options as an associative array with each value as mixed(can be strings, or other arrays). I won't have any objects there.
$keys is a numeric array & the number of keys is determined at runtime.
I want to have a result similar to this expression
$options[$keys[0]][$keys[1]].......[$keys[count($keys)-1]] = $value;
For example, if $keys = array('key1'), i want to do
$options['key1'] = $value;
& if $keys = array('key1', 'key2'), i want to do
$options['key1']['key2'] = $value;
& so on
The problem with array_replace_recursive is that $value may itself be an array. Someway to constrain the depth to which array_replace_recursive can go? or maybe some other way?
I made something similar like this:
$options = array('key1' => array('key2' => array('key3' => 'value')));
$keys = array('key1', 'key2', 'key3');
$search = &$options;
foreach ($keys as $key) {
$search = &$search[$key];
}
$search = 'changed value';
var_dump($options);
You could always create references to the next key.
I think this is not possible, As array is a data structure and you can not put code or loop inside it. Let me google i will update you once i get some solution :)
I finally got it working. Thanks to #Benjamin Paap. His answer helped to get to the exact solution
$options = array('key1' => array('key2' => array('key3' => 'value')));
$keys = array('key1', 'key2', 'key3');
$length = count($keys);
$search = &$options;
foreach ($keys as $key => $value) {
// key doesn't exist or value is not an array
if(!isset($search[$value]) || !is_array($search)) {
$search = (array) $search;
$search[$value] = array();
}
$search = &$search[$value];
// last iteration
if($length - 1 === $key) {
$search = 'new value';
}
}
unset($search);
var_dump($options);