Adding values to a multidimensional array PHP - php

I have tried this now about 20 different ways, set it down and picked it back up several times and I am at a loss for what I am doing wrong. I am trying to create an array of arrays from three separate arrays. The first array I iterate through is a list of dates. Then I iterate through a list of cabins (this is a simple camp scheduling program), and then I randomly assign an activity to each of the cabins from a third array.
The three arrays are $cabins, $activities, and $checkeddates
//swaps key-value so cabin names are keys
$cabins = array_flip( $cabins );
//sets each key value pair to be cabinname=> null
erase_val( $cabins );
foreach ( $checkeddates as $dates ) {
$uberarray[] = $dates;
}
$uberarray = array_flip( $uberarray );
foreach ( $uberarray as $k => $v ) {
$uberarray[$k] = $cabins;
}
At this point, a var_dump shows that I have an array of dates each containing an array of cabins names with null values, from this point I have tried a dozen things and this is just where I left it, trying a process of elimination to figure out what it isn't.
foreach ( $uberarray as $k => $v ) {
shuffle( $activities );
$s = $activities[0];
$uberarray[] = $s;
}
In the end, I was thinking to build the large array (with some additional rules not yet written in to prevent multiple assignments of the same thing and such. And then as one function I would iterate through the established combinations in the array to write it to the database.
Edit: Request for how I want it to look in the end:
array
'ThuJan1st' =>
array
'cabin 1' => randomactivity1
'cabin 2' => randomactivity2
'cabin 3' => randomactivity3
Currently I have 2 out of 3, but I can not seem to randomly add the activities as values.
Edit: This is what #kunal 's suggestion produced:
array
'ThuJan1st' =>
array
'cabin 1' => randomactivity1
'cabin 2' => randomactivity2
'cabin 3' => randomactivity3
array
'FriJan2nd' =>
array
'cabin 1' => randomactivity4
'cabin 2' => Null
'cabin 3' => Null
Once it iterated through activities a single time, nothing else was assigned a value.

foreach ($checkeddates as $date) {
shuffle( $activities );
foreach ($cabins as $cabin) {
foreach ($activities as $activity) {
$uberarray[$date][$cabin] = $activity;
}
}
}
EDIT: The above answer is incorrect. It assigns the same activity to each date/cabin pair. The below answer should give you what you are looking for.
$checkeddates = array('ThuJan1st');
$cabins = array('cabin 1','cabin 2','cabin 3');
foreach ($checkeddates as $date) {
$activities = array('randomactvitiy1','randomactivity2','randomactivity3');
shuffle( $activities );
foreach ($cabins as $cabin) {
$uberarray[$date][$cabin] = array_pop($activities);
}
}
var_dump($uberarray);

Related

How to merge a flat array and a multidim array based on indexes and sum subarray column values?

There are two arrays:
$arr1 = [
"Value1",
"Value2",
"Value1"
];
$arr2 = [
["key_1" => "5", "key_2" => "10"], // relates to Value1
["key_1" => "2", "key_2" => "4"], // relates to Value2
["key_1" => "50", "key_2" => "100"] // relates to Value1
];
I cannot simply combine the two arrays because the duplicated values in $arr1 will lead to overwritten data from $arr2.
The behavior that I need is for subarray data to be added if a value from $arr1 is encountered more than once.
I tried to find all sorts of folding options while searching the web, but I could find anything that was right.
I need this output from the sample input arrays:
array (
'Value1' =>
array (
'key_1' => 55,
'key_2' => 110,
),
'Value2' =>
array (
'key_1' => '2',
'key_2' => '4',
),
)
I've tried to write a solution, but I'm not really sure how to tackle the problem.
foreach ($items as $item) {
if (isset($bal[$item['bonus_name']])) {
//Here I don't know how to sum a new one to the repetition?
} else {
$bal[$item['bonus_name']] = $item['bonus_count'];
}
}
Whatever I try, there's no way to sum a repetitive array of elements. I need some help.
Loop the first array to declare the index -> group relationship.
Check if the currently encountered group is unique to the output array. If so, push the entire subarray from the corresponding index in the second array into the output array as the initial values of the group.
If the group is encountered more than once, add each column value to the related amount in the group's subarray.
Code: (Demo)
$result = [];
foreach ($arr1 as $index => $group) {
if (!isset($result[$group])) {
$result[$group] = $arr2[$index];
} else {
foreach ($arr2[$index] as $key => $value) {
$result[$group][$key] += $value;
}
}
}
var_export($result);

Working with multidimensional array with PHP

I have this array:
$datas = array(
array(
'id' => '1',
'country' => 'Canada',
'cities' => array(
array(
'city' => 'Montreal',
'lang' => 'french'
),
array(
'city' => 'Ottawa',
'lang' => 'english'
)
)
)
);
Question 1:
How can I get the the country name when I have the id ?
I tried: $datas['id'][1] => 'country'
Question 2:
How can I loop in the cities when I have the id ?
I tried:
foreach ($datas as $data => $info) {
foreach ($info['cities'] as $item) {
echo '<li>'.$item['city'].'</li>';
}
}
Thanks a lot.
You have the ID of the array you want analyse, but your array is structured as a map, meaning that there are no keys in the outer array. You will therefore have to iterate the array first to find the object you are looking for.
While the first approach would be to search for the object that has the ID you are looking for, i suggest you map your arrays with their IDs. To do that, you can use two PHP array functions: array_column and array_combine.
array_column can extract a specific field of each element in an array. Since you have multiple country objects, we want to extract the ID from it to later use it as a key.
array_combine takes two arrays with the same size to create a new associative array. The values of the first array will then be used as keys, while the ones of the second array will be used as values.
$mappedCountries = array_combine(array_column($datas, 'id'), $datas);
Assuming that the key 1 is stored in the variable $key = 1;, you can afterwards use $mappedCountries[$key]['country'] to get the name of the country and $mappedCountries[$key]['cities'] to get the cities, over which you can then iterate.
if there might be many arrays in $datas and you want to find one by id (or some other key) you can do something like this:
function search($datas, $key, $value) {
foreach($datas as $data) {
if ($data[$key] === $value) {
return $data;
}
}
So if you want to find where id = 1
$result = search($datas, 'id', '1');
and then you can get country echo $result['country'] or whatever you need.

Restructuring Multi Dimensional Array Format

I am struggling with what would appear to be a pretty straight forward task. I have looked at and tried all kinds of functions and suggestion on SO hoping that maybe there is something simple and functional out there. Nothing I tried gives me the logic to do the restructuring.
I have a long complex array. However very much simplified the logic problem I am trying to solve generically is as follows:
$cost_type = Array
(
0 => "ISP2",
1 => "ISP3",
2 => "ISP4"
);
$supplier_name = Array
(
0 => "NAME-A",
1 => "NAME-B",
2 => "NAME-C"
);
$propertyid = Array
(
0 => "property1",
1 => "property2",
2 => "property2"
);
and I need to convert it to the following set of arrays (noting the concatenation of the two arrays with a common property id.....
$property1
(
array['charges']
[0] =>IPS2
array ['names']
[0] =>NAME-A
)
$property2
(
array['charges']
[0] ->IPS3
[1] =>IPS4
array['names']
[0] =>NAME-B
[1] =>NAME-c
)
I have tried everything over the course of the last few hours and a simple solution totally evades me.
If you can join the three arrays as you say in comments above this code will generate the look you want.
I loop through the array with property and keep key as the key to find names and charges in the other subarrays.
$cost_type = Array
(
0 => "ISP2",
1 => "ISP3",
2 => "ISP4"
);
$supplier_name =Array
(
0 => "NAME-A",
1 => "NAME-B",
2 => "NAME-C"
);
$propertyid = Array
(
0 => "property1",
1 => "property2",
2 => "property2"
);
$arr[] = $cost_type;
$arr[] = $supplier_name;
$arr[] = $propertyid;
$result = array();
Foreach($arr[2] as $key => $prop){
$result[$prop]["charges"][] =$arr[0][$key];
$result[$prop]["names"][] = $arr[1][$key];
}
Var_dump($result);
https://3v4l.org/EilvE
The following code converts the original array in the expected result:
$res = array();
foreach($arr[2] as $k => $foo){ // foreach property
if(!isset($res[$foo])){ // add property if not yet in list
$res[$foo] = array(
'charges' => array($arr[0][$k]),
'names' => array($arr[1][$k])
);
}else{ // add new value to already existing property
$res[$foo]['charges'][] = $arr[0][$k];
$res[$foo]['names'][] = $arr[1][$k];
}
}
Check it out here: https://eval.in/904473
Of course, it assumes a bunch on things about the data, but it should work for any number of items.
And if you need the property in another variable, just access it with $res['name of it].
Run this code you will get smiler result as you want :
$twodimantion=array();
$properties=array('property1','property2','property3');
$charges=array('ISP2','ISP3','ISP4');
$names=array('NAME-A','NAME-B','NAME-C');
foreach ($properties as $key => $property) {
$twodimantion['charge'][$key]=$charges[$key];
$twodimantion['names'][$key]=$names[$key];
$twoarray[$property]=$twodimantion;
}
echo '<pre>';
print_r($twoarray);
echo '</pre>';
I can't say I completely follow what you are trying to do, but I think this may be part of the way there for you.
When trying to restructure data in PHP, it's often helpful to create a empty array (or other data structure) to store the new data in first. Then you find a way to loop over your initial data structure that allows you to insert items into your reformatted structure in the right sequence.
<?php
$properties = []; // Array to hold final result
// Loop over your initial inputs
foreach ($groupsOfValues as $groupName => $groupValues) {
$temp = []; // Array to hold each groupings reformatted data
// Loop over the items in one of the inputs
for ($i=0; $i<count($group) && $i<count($properties)+1; $i++) {
if (!is_array($temp[$groupName])) {
$temp[$groupName] = [];
}
$temp[$groupName][] = $group[$i];
}
$properties[] = $temp;
}

Find value of sibling key in php array

I have an array in PHP, here is a snippet:
$locations = array(
array(
"id" => 202,
"name" => "GXP Club - Fable"
),
array (
"id" => 204,
"name" => "GXP Club - Gray"
)
);
What I know (from a GET) is the ID (202). What I would like to display is
"Showing results for "
( where $locations[?][id] = $_GET['id'] { echo $locations[?][name] } )
- if you will pardon my use of pseudo code.
Not sure what function is best or if I need to loop over the whole array to find that. Thanks.
Edit: for further clarification. I need to learn the [name] given the [id]
foreach( $locations as $arr ) {
if($arr['id'] == $_GET['id']) {
echo $arr['name'];
break;
}
}
That should do the trick.
While looping over the array is the solution for the problem as described, it seems more optimal to change your array to be $id=>$name key-value pairs, instead of named key values if that's all the data in the array, e.g.:
$locations = array( '202' => 'GXP Club - Fable',
'204' => 'GXP Club - Gray',
)
Alternatively, if there's more data, I'd switch to a nested data structure, e.g.:
$locations = array( '202' => array( 'name' => 'GXP Club - Fable', 'prop2' =>$prop2, etc),
'204' => array( 'name' => 'GXP Club - Gray', 'prop2' =>$prop2, etc),
)
That makes it so you can access data via ID (e.g. $locations[$id]['name']), which seems to be what you'd generally be wanting to do.
You can use array_map function which applies your custom action to each element in given array.
array_map(
function($arr) { if ($arr['id'] == $_GET['id']) echo $arr['name']; },
$locations
);
Doing this with PHP's built-in array functions* avoids a foreach loop:
<?php
$locations = [["id"=>202, "name"=>"GXP Club - Fable"], ["id"=>204, "name"=>"GXP Club - Gray"]];
$col = array_search(array_column($locations, "id"), $_GET["id"]);
echo $locations[$col]["name"];
Or, using a different method:
<?php
$locations = [["id"=>202, "name"=>"GXP Club - Fable"], ["id"=>204, "name"=>"GXP Club - Gray"]];
$result = array_filter($locations, function($v){ return $v["id"] == $_GET["id"]; });
echo array_shift($result)["name"];
* Notably, array_column() was not available until PHP 5.5, released 10 months after this question was asked!

Understanding the basics of multidimensional arrays

I am new to using multidimensional arrays with php, I have tried to stay away from them because they confused me, but now the time has come that I put them to good use. I have been trying to understand how they work and I am just not getting it.
What I am trying to do is populate results based on a string compare function, once I find some match to an 'item name', I would like the first slot to contain the 'item name', then I would like to increment the priority slot by 1.
So when when I'm all done populating my array, it is going to have a variety of different company names, each with their respective priority...
I am having trouble understanding how to declare and manipulate the following array:
$matches = array(
'name'=>array('somename'),
'priority'=>array($priority_level++)
);
So, in what you have, your variable $matches will point to a keyed array, the 'name' element of that array will be an indexed array with 1 entry 'somename', there will be a 'priority' entry with a value which is an indexed array with one entry = $priority_level.
I think, instead what you probably want is something like:
$matches[] = array(name => 'somename', $priority => $priority_level++);
That way, $matches is an indexed array, where each index holds a keyed array, so you could address them as:
$matches[0]['name'] and $matches[0]['priority'], which is more logical for most people.
Multi-dimensional arrays are easy. All they are is an array, where the elements are other arrays.
So, you could have 2 separate arrays:
$name = array('somename');
$priority = array(1);
Or you can have an array that has these 2 arrays as elements:
$matches = array(
'name' => array('somename'),
'priority' => array(1)
);
So, using $matches['name'] would be the same as using $name, they are both arrays, just stored differently.
echo $name[0]; //'somename';
echo $matches['name'][0]; //'somename';
So, to add another name to the $matches array, you can do this:
$matches['name'][] = 'Another Name';
$matches['priority'][] = 2;
print_r($matches); would output:
Array
(
[name] => Array
(
[0] => somename
[1] => Another Name
)
[priority] => Array
(
[0] => 1
[1] => 2
)
)
In this case, could this be also a solution with a single dimensional array?
$matches = array(
'company_1' => 0,
'company_2' => 0,
);
if (isset($matches['company_1'])) {
++$matches['company_1'];
} else {
$matches['company_1'] = 1;
}
It looks up whether the name is already in the list. If not, it sets an array_key for this value. If it finds an already existing value, it just raises the "priority".
In my opinion, an easier structure to work with would be something more like this one:
$matches = array(
array( 'name' => 'somename', 'priority' => $priority_level_for_this_match ),
array( 'name' => 'someothername', 'priority' => $priority_level_for_that_match )
)
To fill this array, start by making an empty one:
$matches = array();
Then, find all of your matches.
$match = array( 'name' => 'somename', 'priority' => $some_priority );
To add that array to your matches, just slap it on the end:
$matches[] = $match;
Once it's filled, you can easily iterate over it:
foreach($matches as $k => $v) {
// The value in this case is also an array, and can be indexed as such
echo( $v['name'] . ': ' . $v['priority'] . '<br>' );
}
You can also sort the matched arrays according to the priority:
function cmp($a, $b) {
if($a['priority'] == $b['priority'])
return 0;
return ($a['priority'] < $b['priority']) ? -1 : 1;
}
usort($matches, 'cmp');
(Sourced from this answer)
$matches['name'][0] --> 'somename'
$matches['priority'][0] ---> the incremented $priority_level value
Like David said in the comments on the question, it sounds like you're not using the right tool for the job. Try:
$priorities = array();
foreach($companies as $company) {
if (!isset($priorities[$company])) { $priorities[$company] = 0; }
$priorities[$company]++;
}
Then you can access the priorities by checking $priorities['SomeCompanyName'];.

Categories