PHP Laravel Foreach trough multi array - php

I have the following multi dimension array and I am not able to do a foreach loop (with laravel). I want to show the name.
Any idea how to loop trough that array to show just the name? I reduced the showed array -> ...
I want to loop trough that array not in a view but in a controller because i want to create a database entry for every client
array:1 [▼
"client" => array:52 [▼
0 => array:11 [▼
"name" => "Company One"
...
]
1 => array:11 [▼
"name" => "Company 2"
...
]
Thanks for your help.

$array = [
'client' => [
[
'name' => 'Company One',
'foo' => 'Foo One',
],[
'name' => 'Company 2',
'foo' => 'Foo 2',
]
]
];
$names = array_pluck($array['client'], 'name');
foreach($names as $name) {
echo $name; // Replace this with the logic to create DB entry
}

Its easy all you have to do is this ,lets assume that your array are in the varibale $myArray
$myArray = [▼
"client" => array:52 [▼
0 => array:11 [▼
"name" => "Company One"
...
]
1 => array:11 [▼
"name" => "Company 2"
...
]
then you have to do:
#foreach ($myArray->client as $data)
{{$data->name}}
#endforeach

Related

Foreach - Array inside another array - Returns only 1 index - I need to return all values ​of key_number:

I want to get from my answer only the values ​​of the key_number; even though I return the foreach inside another foreach, it returns only one index and not the two values ​​of the request.
Controller
foreach (array($request['key_number']) as $notaFiscal) {
foreach($notaFiscal as $notas) {
dd($notas);
}
// $moviment->document()->create($notasFiscais);
}
Request
dd($request);
+request: Symfony\Component\HttpFoundation\InputBag {#1535
#parameters: array:8 [
"type" => null
"people_id" => 5
"company_id" => 1
"vehicle_id" => 2
"department_id" => "12179"
"document_id" => null
"document_type_id" => 1
"key_number" => array:2 [
0 => array:2 [
"title" => "New Title"
"key_number" => "444444"
]
1 => array:2 [
"title" => "New Title"
"key_number" => "555555"
]
]
]
}
Request foreach index key_number
array:2 [ // app\Http\Controllers\MovimentController.php:50
0 => array:2 [
"title" => "New Title"
"key_number" => "444444"
]
1 => array:2 [
"title" => "New Title"
"key_number" => "555555"
]
]
foreach inside foreach return only one index
array:2 [ // app\Http\Controllers\MovimentController.php:51
"title" => "New Title"
"key_number" => "444444"
]
Return all index key_number, not one index.

How to get multiple arrays from an array in php?

I have he next array looks like:
array:50 [▼
0 => array:39 [▶]
1 => array:39 [▶]
2 => array:39 [▶]
]
So I want to get arrays with a value in common, for example:
array:39 [▼
"id" => 121
"user" => 368
]
array:39 [▼
"id" => 121
"user" => 3687
]
array:39 [▼
"id" => 500
"user" => 452
]
I want to get the two arrays with the attribute
id 121, I was trying to looping the array with foreach looks like:
foreach ($info as $val){
foreach($info as $f ){
if($f["id"]==$val["id"]){
//get the multiple arrays
}
}
}
So, I can't get all the arrays, some idea to how can do that?
I'd use a Collection.
collect your array of arrays:
$collection = collect([
[
"id" => 121
"user" => 368
],
[
"id" => 121
"user" => 3687
],
[
"id" => 500
"user" => 452
]
]);
Use the where method to filter based on a specific key's value:
$filtered = $collection->where('id', 121);
$filtered->all();
/*
[
['id' => '121', 'user' => 368],
['id' => '121', 'user' => 3687],
]
*/
Other where-like methods are available. Be sure to read through all of the documentation on Collections, it's full of great examples!
If you're now convinced that you should use Collections for everything, check out Adam Wathan's awesome book (and other resources): Refactoring to Collections (not free)

Passing array of arrays to blade

I have a problem to passing array of arrays from controller to view in Laravel. I've done some research but none of topics helped. My tables are Shops, Items, Items Price. Shops contains shop id, which I get for use from url application/id. In Items Price I got information like shop_id , item_id (these two are FK), price. This table shows which items are in which shops. And in Items I have information about items: id ,picture. When I go to application/1, I want site to show items, which are in this specific shop, information.
My controller method:
public function getItems($id)
{
$items=ItemPrice::where('shop_id', $id)->select('item_id')->get()->toArray();
foreach($items as $item)
$products[] = array(Item::where('id',$item)->get()->toArray());
$shops=Shop::all();
return view('shop')->with(compact(['products','shops']));
}
when I debugging array with dd($products); I get:
array:4 [▼
0 => array:1 [▼
0 => array:1 [▼
0 => array:5 [▼
"id" => 1
"name" => "Item1"
"price" => 0.8
"type" => 2
"img_dir" => "svg/d.jpg"
]
]
]
1 => array:1 [▼
0 => array:1 [▼
0 => array:5 [▼
"id" => 2
"name" => "Item2"
"price" => 1.1
"type" => 2
"img_dir" => "svg/d2.jpg"
]
]
]
2 => array:1 [▼
0 => array:1 [▼
0 => array:5 [▼
"id" => 3
"name" => "Item3"
"price" => 3.1
"type" => 5
"img_dir" => "svg/p1.jpg"
]
]
]
3 => array:1 [▼
0 => array:1 [▼
0 => array:5 [▼
"id" => 4
"name" => "Item4"
"price" => 1.56
"type" => 5
"img_dir" => "svg/p2.jpg"
]
]
]
]
In view I do foreach #foreach($products as $product) and I get error:
Trying to get property 'img_dir' of non-object.
Any help would be appreciated.
Try like this
public function getItems($id)
{
$items = ItemPrice::where('shop_id', $id)
->select('item_id')
->pluck('item_id')
->toArray();
$products = Item::whereIn('id', $items)->get();
$shops = Shop::all();
return view('shop', compact('products','shops'));
}
You have some nested arrays in $products. What you think is a product is in fact an array. Maybe if you simplify your $products variable content :
public function getItems($id) {
$items = ItemPrice::where('shop_id', $id)->select('item_id')->get()->toArray();
$products = [];
foreach($items as $item) {
$products[] = Item::where('id',$item)->get();
}
$shops = Shop::all();
return view('shop')->with(compact(['products', 'shops']));
}
Look at this line
$products[] = array(Item::where('id',$item)->get()->toArray());
$products is an array, and you assign a new element which is an array made by the array value of your query (which contains array).
So you have a 3-level nested array which leads to confusion.
Why don't you just send to your blade view $products = Item::where('id',$item)->get(); ?

How to store the quantity in the $regTypes array?

I want to have an array with the info about each registration type associated with a registration. For example if for the registration with id "1" the user selected two registration types of type "General" and one of the type "Plus" the $regTypes array should have this content with 2 item:
'registrationTypes' => [
[
'name' => 'general',
'price' => '5',
'quantity' => '2'
],
[
'name' => 'plus',
'price' => '10',
'quantity' => '1'
]
]
The registration_types table have the name and the price. So I have this query to get some info about a registration in a conference.
$registration = Registration
::with('conference', 'Conference.registrationTypes')->where('id', 1)->first();
And then I have this code to create the array with the necessary info:
$regTypes = [];
foreach($registration->conference->registrationTypes as $key=>$registrationType){
$regTypes [
'regType' => [
'name' => $registration->conference->registrationTypes[$key]['name'],
'price' => $registration->conference->registrationTypes[$key]['price']
]
];
}
My doubt is how to also store the quantity in the $regTypes array. Because the quantity is not stored in the database.
Maybe to get the quantity is necessary to do antoher query. With this code below:
$registrationTypeDetails = Registration::with('participants:id,registration_type_id,registration_id')->find($regID);
//dd($registrationTypeDetails);
$type_counts = [];
foreach ($registrationTypeDetails->participants as $p) {
$name = $p->registration_type->name;
if (!isset($type_counts[$name])) {
$type_counts[$name] = 0;
}
$type_counts[$name]++;
}
dump($type_counts);
The $type_counts shows the quantity of each registration type associated with the registration:
array:2 [▼
"general" => 2
"plus" => 1
]
Do you know how to use this $type_counts content to store the quantity properly in the $regTypes array?
To directly answer your question (IE not change the controller code, just "use this $type_counts content to store the quantity properly in the $regTypes array"), I'm hopeful this should work for you:
$regTypes = [];
foreach($registration->conference->registrationTypes as $key=>$registrationType){
$typeName = $registration->conference->registrationTypes[$key]['name'];
$regTypes [
'regType' => [
'name' => $typeName,
'price' => $registration->conference->registrationTypes[$key]['price'],
'quantity' => $type_counts[$typeName]
]
];
}
Basically just pulling the count from the $type_counts array based on the name of the Registration Type being the key that you added in the foreach ($registrationTypeDetails->participants as $p) loop.
Depending upon what you are after, it might be easier just to loop on the registration types, rather than go through $registration->conference->registrationTypes. This way you don't have duplicates. But that assumes you don't want duplicates :)
I hope this code useful for you .If you need the number of participants in any type, you can use the following code:
$registration = Registration::with('conference','Conference.registrationTypes','Conference.registrationTypes.participants')
->where('id',$regID)->first();
$result=$registration->conference->registrationTypes->each(function ($item, $key) use($registration) {
$item['try_count']=$item->participants->count();
});
dd($result->toArray());
I added the try_count variable to the final result:
array:2 [▼
0 => array:6 [▼
"id" => 1
"name" => "general"
"price" => 0
"conference_id" => 1
"try_count" => 8
"participants" => array:8 [▼
0 => array:5 [▶]
1 => array:5 [▶]
2 => array:5 [▶]
3 => array:5 [▶]
4 => array:5 [▶]
5 => array:5 [▶]
6 => array:5 [▶]
7 => array:5 [▶]
]
]
1 => array:6 [▼
"id" => 2
"name" => "plus"
"price" => 1
"conference_id" => 1
"try_count" => 5
"participants" => array:5 [▼
0 => array:5 [▶]
1 => array:5 [▶]
2 => array:5 [▶]
3 => array:5 [▶]
4 => array:5 [▶]
]
]
]

Push a set of values to an array based on another unique value in the same array

Question background
Hello, I have the following array of movie crew members:
array:7 [▼
0 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5e9d"
"department" => "Directing"
"id" => 139098
"job" => "Director"
"name" => "Derek Cianfrance"
"profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
]
1 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5ed7"
"department" => "Writing"
"id" => 139098
"job" => "Story"
"name" => "Derek Cianfrance"
"profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
]
2 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5edd"
"department" => "Writing"
"id" => 132973
"job" => "Story"
"name" => "Ben Coccio"
"profile_path" => null
]
3 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5ee3"
"department" => "Writing"
"id" => 139098
"job" => "Screenplay"
"name" => "Derek Cianfrance"
"profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
]
4 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5ee9"
"department" => "Writing"
"id" => 132973
"job" => "Screenplay"
"name" => "Ben Coccio"
"profile_path" => null
]
5 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5eef"
"department" => "Writing"
"id" => 1076793
"job" => "Screenplay"
"name" => "Darius Marder"
"profile_path" => null
]
11 => array:6 [▼
"credit_id" => "52fe49de9251416c750d5f13"
"department" => "Camera"
"id" => 54926
"job" => "Director of Photography"
"name" => "Sean Bobbitt"
"profile_path" => null
]
]
As you can see this is a list of credits I'm getting via the TMDb API. The first step of building the above array was to filter out all jobs that I don't want to display, here's how I did that:
$jobs = [ 'Director', 'Director of Photography', 'Cinematography', 'Cinematographer', 'Story', 'Short Story', 'Screenplay', 'Writer' ];
$crew = array_filter($tmdbApi, function ($crew) use ($jobs) {
return array_intersect($jobs, $crew);
});
My question
I'd like to figure out how to take the above result one step further and combine jobs where the id is the same, so as to end up with something like this, for example:
array:7 [▼
0 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5e9d"
"department" => "Directing"
"id" => 139098
"job" => "Director, Story, Screenplay"
"name" => "Derek Cianfrance"
"profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
]
I have also considered ditching doing this in my logic and instead doing it in my blade template, but I'm not sure how to achieve that.
How would you accomplish this?
You could nicely use Laravel's Collection in such a situation, which has a great number of methods which will help you in this case.
First, turn this array (the one you already filtered on jobs) to a Collection:
$collection = collect($crew);
Second, group this Collection by it's ids:
$collectionById = $collection->groupBy('id');
Now, the results are grouped by the id and transformed to a Collection in which the keys correspond to the id, and the value an array of 'matching' results. More info about it here.
Finally, just a easy script that iterates through all the results for each id and combines the job field:
$combinedJobCollection = $collectionById->map(function($item) {
// get the default object, in which all fields match
// all the other fields with same ID, except for 'job'
$transformedItem = $item->first();
// set the 'job' field according all the (unique) job
// values of this item, and implode with ', '
$transformedItem['job'] = $item->unique('job')->implode('job', ', ');
/* or, keep the jobs as an array, so blade can figure out how to output these
$transformedItem['job'] = $item->unique('job')->pluck('job');
*/
return $transformedItem;
})->values();
// values() makes sure keys are reordered (as groupBy sets the id
// as the key)
At this point, this Collection is returned:
Collection {#151 ▼
#items: array:4 [▼
0 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5e9d"
"department" => "Directing"
"id" => 139098
"job" => "Director, Story, Screenplay"
"name" => "Derek Cianfrance"
"profile_path" => "/zGhozVaRDCU5Tpu026X0al2lQN3.jpg"
]
1 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5edd"
"department" => "Writing"
"id" => 132973
"job" => "Story, Screenplay"
"name" => "Ben Coccio"
"profile_path" => null
]
2 => array:6 [▼
"credit_id" => "52fe49dd9251416c750d5eef"
"department" => "Writing"
"id" => 1076793
"job" => "Screenplay"
"name" => "Darius Marder"
"profile_path" => null
]
3 => array:6 [▼
"credit_id" => "52fe49de9251416c750d5f13"
"department" => "Camera"
"id" => 54926
"job" => "Director of Photography"
"name" => "Sean Bobbitt"
"profile_path" => null
]
]
}
Note: to use this Collection as an array, use:
$crew = $combinedJobCollection->toArray();
There are multiple ways to achieve this, for example: search the array for overlapping id's, but I think this is the easiest way to achieve this.
Goodluck!
Since you are trying to edit the array elements and its size, I believe array_map() or array_filter() won't be a solution to this.
This is what I could come up with...
$jobs = [
'Director', 'Director of Photography', 'Cinematography',
'Cinematographer', 'Story', 'Short Story', 'Screenplay', 'Writer'
];
$crew = [];
foreach($tmdbApi as $key => $member) {
if($member['id'] == $id && in_array($member['job'], $jobs)) {
if(!isset($crew[$key])) {
$crew[$key] = $member;
} else {
$crew_jobs = explode(', ', $crew[$key]['job']);
if(!in_array($member['job'], $crew_jobs)) {
$crew_jobs[] = $member['job'];
}
$crew[$key]['job'] = implode(', ', $crew_jobs);
}
}
}
Hope this answers your question :)

Categories