I have an $accounts array with this data in it
array:2 [▼
0 => array:25 [▼
"email_address" => "bob#xyzcorp.com"
"account_id" => 111
"password" => "abc"
"account_type" => "admin"
"name_prefix" => "Mr"
"first_name" => "Bob"
"middle_names" => "X."
"last_name" => "Jones"
"name_suffix" => "Jr."
"non_person_name" => false
"DBA" => ""
"display_name" => "BobJ"
"address1" => "111 Park Ave"
"address2" => "Floor 4"
"address3" => "Suite 4011"
"city" => "New York"
"state" => "NY"
"postal_code" => "10022"
"nation_code" => "USA"
"phone1" => "212-555-1212"
"phone2" => ""
"phone3" => ""
"time_zone_offset_from_utc" => -5
"customer_type" => 2
"last_updated_utc_in_secs" => 200200300
]
1 => array:25 [▼
"email_address" => "tom#xyzcorp.com"
"account_id" => 112
"password" => "abd"
"account_type" => "mbn"
"name_prefix" => "Mr"
"first_name" => "Tom"
"middle_names" => "Z."
"last_name" => "Smith"
"name_suffix" => "Sr."
"non_person_name" => false
"DBA" => ""
"display_name" => "TomS"
"address1" => "112 Park Ave"
"address2" => "Floor 3"
"address3" => "Suite 3011"
"city" => "New York"
"state" => "NY"
"postal_code" => "10022"
"nation_code" => "USA"
"phone1" => "212-555-2323"
"phone2" => ""
"phone3" => ""
"time_zone_offset_from_utc" => -5
"customer_type" => 2
"last_updated_utc_in_secs" => 200200300
]
]
I want to construct a new array out of this array.
But the new array I only want to have 2 keys: email_address and the password.
I've tried:
$new_array = array();
$i = 0;
foreach ($accounts as $account) {
$new_array[$i++];
foreach ($account as $user) {
$new_array['email_address'] = $user['email_address'];
$new_array['password'] = $user['password'];
}
}
dd($new_array);
I hope someone can give me a little push here.
You're not adding new elements to $new_array. Each time through the foreach loop you overwrite the same two keys. The elements of $new_array should be arrays.
You also don't need the inner loop, because each account is just one user.
foreach ($accounts as $account) {
$new_array[] = array('email_address' => $account['email_address'],
'password' => $account['password']);
}
You don't need the variable $i, because $new_array[] = pushes a new element onto the array.
$new_array[$i++];
foreach ($account as $user) {
$new_array['email_address'] = $user['email_address'];
$new_array['password'] = $user['password'];
}
Your issue is here, you almost have it, but as you are using the array within the array, with the two sets of foreach loops, you thus need to have the same depth of structure if you want to preserve more than one records' password and email_address.
So, replace the above quote with:
$i++
$new_array[$i];
foreach ($account as $user) {
$new_array[$i]['email_address'] = $user['email_address'];
$new_array[$i]['password'] = $user['password'];
}
This will output
$new_array(
[0] ===> ['password'] --> {data}
===> ['email_address'] --> {data}
[1] ===> ['password'] --> {data}
===> ['email_address'] --> {data}
....
)
Edit:
This can further be reduced and tidied up as:
$i++
$new_array[$i];
$new_array[$i]['email_address'] = $account['email_address'];
$new_array[$i]['password'] = $account['password'];
Because you know the key of the value you want so you don't need to break the outer array apart to find anything, you can get it by direct reference to outerValue (account) and then key(email_address, etc).
Related
This is the first problem:
I have two Associative Arrays, one containing sales persons and one containing clients.
$salesPersons = array(
array(
"id" => "1",
"name" => "Mr Smith",
"email" => "mrsmith#email.com",
"clients" => array()
),
array(
"id" => "2",
"name" => "James Bond",
"email" => "jamesbond#email.com",
"clients" => array()
)
);
$clients = array(
array(
"id" => "1",
"name" => "Lucifer Enterprises",
"salesPersonId" => "1"
),
array(
"id" => "2",
"name" => "Charlies Chocolate Factory",
"salesPersonId" => "1"
),
array(
"id" => "3",
"name" => "Geckos Investments",
"salesPersonId" => "2"
),
);
I want to map $salesPersons['id'] to clients['salesPersonId'] by ID and return a multidimensional associative array like this:
$result_i_want = array(
array(
"id" => "1",
"name" => "Mr Smith",
"email" => "mrsmith#email.com",
"clients" => array(
array(
"id" => "1",
"name" => "Lucifer Enterprises",
),
array(
"id" => "2",
"name" => "Charlies Chocolate Factory",
),
)
),
array(
"id" => "2",
"name" => "James Bond",
"email" => "jamesbond#email.com",
"clients" => array(
array(
"id" => "3",
"name" => "Geckos Investments",
),
)
)
);
My solution to the first problem
I have solved it using nested foreach-loops and array_push
$result = array();
foreach ($clients as $c_record) {
foreach ($salesPersons as $s_record) {
if ($c_record['salesPersonId'] == $s_record['id']) {
array_push($s_record['clients'], array(
"id" => $c_record['id'],
"name" => $c_record['name']
));
array_push($result, $s_record);
}
}
}
The remaining problem
This solution doesn't seem to be very efficient.
For each client record I check all sales persons to see if there is a match. I think the number of computations are:
no. of clients * no. of sales persons
I have a huge database and also need to add even more dimensions by mapping projects to the clients and deliverables to the projects. I think this could pose a problem.
Question
Is there a more efficient way to get the same result?
Build an index :
you need to access your salesPerson entries by id, you can start by creating an associative array id => salesPerson, and then use this associative array in your loop.
$salesById = array();
foreach ($salesPersons as $s_record) {
$salesById[ $s_record['id'] ] = $s_record;
}
$result = array();
foreach ($clients as $c_record) {
$s_record = $salesById[ $c_record['salesPersonId'] ];
if ($s_record == null) {
// you may want to handle invalid ids in the client array
// one way is to simply ignore this client record :
continue;
}
array_push($s_record['clients'], array(
"id" => $c_record['id'],
"name" => $c_record['name']
));
array_push($result, $s_record);
}
Notes
There may be a problem in the way you create your $result array :
if a sales person has n clients, the $result array will reference that sales person n times.
Look closer into what result you actually want, you may simply want to return $salesPersons, or $salesById.
As LeGEC said:
you need to access your salesPerson entries by id, you can start by creating an associative array id => salesPerson, and then use this associative array in your loop.
You need to set the index of your arrays with the id:
<?php
$salesPersons = array(
1 => array(
"id" => "1",
"name" => "Mr Smith",
"email" => "mrsmith#email.com",
"clients" => array()
),
2 => array(
"id" => "2",
"name" => "James Bond",
"email" => "jamesbond#email.com",
"clients" => array()
)
);
$clients = array(
1 => array(
"id" => "1",
"name" => "Lucifer Enterprises",
"salesPersonId" => "1"
),
2 => array(
"id" => "2",
"name" => "Charlies Chocolate Factory",
"salesPersonId" => "1"
),
3 => array(
"id" => "3",
"name" => "Geckos Investments",
"salesPersonId" => "2"
),
);
Then:
$result = array();
foreach ($clients as $id => $c_record) {
if (isset($salesPersons[$id])) {
$result[] = array_merge($clients[$id], $salesPersons[$id]);
} else {
$result[] = $clients[$id];
}
}
var_dump($result);
Result here: http://sandbox.onlinephpfunctions.com/code/e590bdb5aaea2794fc5a04ee60f61db766129664
PS:
My code works with your use case, but it will not work if the size of the $salesPersons array is bigger than the $clients array
I am trying to iterate over this array in order to take all league values (league_id,name,type etc)
array:1 [▼
"api" => array:2 [▼
"results" => 970
"leagues" => array:970 [▼
0 => array:13 [▼
"league_id" => 1
"name" => "World Cup"
"type" => "Cup"
"country" => "World"
"country_code" => null
"season" => 2018
"season_start" => "2018-06-14"
"season_end" => "2018-07-15"
"logo" => "https://media.api-football.com/leagues/1.png"
"flag" => null
"standings" => 1
"is_current" => 1
]
1 => array:13 [▼
"league_id" => 2
"name" => "Premier League"
"type" => "League"
"country" => "England"
"country_code" => "GB"
"season" => 2018
"season_start" => "2018-08-10"
"season_end" => "2019-05-12"
"logo" => "https://media.api-football.com/leagues/2.png"
"flag" => "https://media.api-football.com/flags/gb.svg"
"standings" => 1
"is_current" => 0
]
.......
but until now,with the following code:
$request = json_decode($request->getBody()->getContents(), true);
foreach ($request as $array=>$val) {
foreach ($val['leagues'] as $id) {
dd($id);
}
}
the only thing that i can get is the first array only and not the rest:
array:13 [▼
"league_id" => 1
"name" => "World Cup"
"type" => "Cup"
"country" => "World"
"country_code" => null
"season" => 2018
"season_start" => "2018-06-14"
"season_end" => "2018-07-15"
"logo" => "https://media.api-football.com/leagues/1.png"
"flag" => null
"standings" => 1
"is_current" => 1
]
any help?
The dd() function you are calling is killing the execution of your script on your first iteration.
From the Laravel Docs:
The dd function dumps the given variables and ends execution of the script.
If you do not want to halt the execution of your script, use the dump function instead.
Just iterate over it like so:
$request = json_decode($request->getBody()->getContents(), true);
foreach ($request['leagues'] as $id=>$league) {
print_r(compact('id', 'league')); // To see the id and value array
}
Hope this helps,
I have a form request which I need to validate . If I dd the $request->all() it shows me the following result.
"adults_information" => array:1 [▼
0 => array:6 [▼
"first_name" => "Luke"
"last_name" => "Greer"
"dob_day" => "08"
"dob_month" => "01"
"dob_year" => 1935
"gender" => "M"
]]
"contact_name" => "Eula Dennis"
"mobile_number" => "7308001726"
What I want is to create extra field after dob_year such as dob which constist of calculation of dob_day,"dob_year","dob_month" . I want some line of code such that when I do dd($request->all()) . I want to get the output like this .
"adults_information" => array:1 [▼
0 => array:6 [▼
"first_name" => "Luke"
"last_name" => "Greer"
"dob_day" => "08"
"dob_month" => "01"
"dob_year" => 1935
"gender" => "M",
"dob"=>"1935-01-08"
]]
"contact_name" => "Eula Dennis"
"mobile_number" => "7308001726"
I tried $request->add() but it didn't work . Any help will be appriciated
The correct syntax is not $request->add but $request->request->add.
So:
$request->request->add([
'adults_information'=>$request->adults_information + ['dob' => '1935-01-08']
]);
$inputs = $request->all();
foreach($inputs['adults_information'] as $key => $info)
{
$dob = $info['dob_year'].'-'.
$info['dob_month'].'-'.
$info['dob_day'];
$inputs['adults_information'][$key]['dob'] = $dob;
}
$request->merge($inputs);
dd($request->all());
Hi u can use merge() with array_push to push a nested array.
$adults_information = $request->adults_information;
$insert = [
"first_name" => "Luke",
"last_name" => "Greer",
"dob_day" => "08",
"dob_month" => "01",
"dob_year" => 1935,
"gender" => "M",
"dob"=>"1935-01-08"
];
array_push($adults_information, $insert);
$request->merge('adults_information', $adults_information);
https://laravel.com/docs/5.6/requests
Hope this helps
You can use replace method for appending item to request object. For more details you can check Laravel API docs https://laravel.com/api/5.6/Illuminate/Http/Request.html#method_replace . For example.
$data = $request->all();
$data['appending_data_1'] = 'dummy value';
$data['appending_data_2'] = 'dummy value';
$request->replace($data);
I am using foreach loop that outputs an array
$dinnerDetails = array();
$lastDinnerDate = '';
$newDate = '';
foreach ($invitations as $invitation) {
$lastDinnerDate = $invitation['dinner_date'];
if ($invitation['dinner_date'] > $lastDinnerDate) {
$newDate = 'yes';
} else {
$newDate = 'no';
}
$dinnerDetails[] = array(
'request_id' => $invitation['request_id'],
'dinner_date' => $invitation['dinner_date'],
'dinner_id' => $invitation['dinner_id'],
'new_dinner' => $newDate
);
}
Output looks like this
array:4 [▼
0 => array:3 [▼
"request_id" => "48"
"dinner_id" => "36"
"dinner_date" => "2016-05-16T10:00:00"
"new_date" => "yes"
]
1 => array:3 [▼
"request_id" => "51"
"dinner_id" => "40"
"dinner_date" => "2016-05-16T10:00:00"
"new_date" => "no"
]
2 => array:3 [▼
"request_id" => "50"
"dinner_id" => "36"
"dinner_date" => "2016-05-27T10:00:00"
"new_date" => "yes"
]
3 => array:3 [▼
"request_id" => "52"
"dinner_id" => "41"
"dinner_date" => "2016-05-27T10:00:00"
"new_date" => "no"
]
]
My question is how can i count the number of times the dinner_id appeared. I would like to pass that value as part of the array because $dinnerDetails is being passed to the view so it will make it easier to display the count. The view already displays the data via foreach loop its only the count i need for each dinner_id
I assume you want to count the ID's and not the label / name itself, one ever so simple way would be doing it like so, simply place this inside of your foreach loop
$countDinner[$invitation['dinner_id']] = isset($countDinner[$invitation['dinner_id']]) ? $countDinner[$invitation['dinner_id']] + 1 : 1;
One coud also use a if clause instead of a ternary operator if one preffers, don't forget to place a
$countDinner = array();
Before the foreach loop to initialize the array, you should now have a array with the count of each dinner_id.
To add it to the existing array simply loop through as following:
foreach($dinnerDetails as &$dinnerDetail){
$dinnerDetail['count'] = $countDinner[$dinnerDetail['dinner_id']];
}
and the end result will look like this
0 => array:3 [▼
"request_id" => "48"
"dinner_id" => "36"
"dinner_date" => "2016-05-16T10:00:00"
"new_date" => "yes"
"count" => 2
]
I am working on a cron job script and the purpose of the script is to send dinner details to the user, now the user should ONLY get the dinner details in email that they are attending.
Since it is a cron job so what happens is the query pulls all the dinners from database and puts the result in an array() which looks like this.
CronController.php on line 79:
array:3 [▼
0 => array:19 [▼
"request_id" => "50"
"dinner_id" => "35"
"dinner_name" => "Black Tie"
"dinner_status" => "pending"
"dinner_date" => "2016-05-27T10:00:00"
"guest_first_name" => "x"
"guest_last_name" => "y"
"guest_user_id" => "78"
"dinner_host" => "77"
"host_email" => "xyz#example2.com"
"host_first_name" => "News 12"
"host_last_name" => "News 12"
"host_user_id" => 55
]
1 => array:19 [▼
"request_id" => "50"
"dinner_id" => "35"
"dinner_name" => "Black Tie"
"dinner_status" => "pending"
"dinner_date" => "2016-05-27T10:00:00"
"guest_first_name" => "x"
"guest_last_name" => "y"
"guest_user_id" => "78"
"dinner_host" => "77"
"host_email" => "abcd#example1.com"
"host_first_name" => "Demo First"
"host_last_name" => "Demo Last"
"host_user_id" => 77
]
2 => array:19 [▼
"request_id" => "51"
"dinner_id" => "36"
"dinner_name" => "Black Tie"
"dinner_status" => "pending"
"dinner_date" => "2016-05-16T10:00:00"
"guest_first_name" => "x"
"guest_last_name" => "y"
"guest_user_id" => "78"
"dinner_host" => "77"
"host_email" => "abcd#example1.com"
"host_first_name" => "Demo First"
"host_last_name" => "Demo Last"
"host_user_id" => 77
]
]
Now you will notice host_email for the first its xyz#example2.com so this person should only get that dinner details and not the second and third, similarly for the second and third result you will notice the host_email is same abcd#example1.com so this user should get only 1 email containing details of both dinners.
I have in past generated emails in PHP but never in this way so I am stuck on how to even begin this. I will really appreciate any help in this.
Iterate over your array to rearrange it.
$mails = array();
foreach ($array as $messageArray) {
$mails[$messageArray['host_email']][] = $messageArray;
}
Now you have your messages grouped by host_email and can just iterate over it and stack the messages.
Like this:
$array = array(
array(
"host_email" => "test#dfsd.com",
"text" => "hello you",
),
array(
"host_email" => "SomeoneElse#what.uk",
"text" => "I am hungry",
),
array(
"host_email" => "test#dfsd.com",
"text" => "hello you 2",
),
);
$mails = array();
foreach ($array as $messageArray) {
$mails[$messageArray['host_email']][] = $messageArray;
}
// outer Loop to create mailheader and to send the mail after creating the message
foreach ($mails as $to=> $messages) {
$subject = 'eating';
$mailHeader = '...';
$mailBody = '';
// inner loop to stick the messages together that have the same recipent
foreach ($messages as $value) {
$mailBody .= $value['text'] . "\n\r";
}
mail($to, $subject, $mailBody, $mailHeader);
}