recursive function transform nested array - php

Im my laravel project I have this nested array that needs to be updated (transformed - for the frontend):
array:2 [
0 => array:3 [
"entity_id" => 931
"entity" => "user"
"children" => array:2 [
0 => array:2 [
"entity_id" => 5
"entity" => "location"
]
1 => array:2 [
"entity_id" => 932
"entity" => "user"
]
]
]
1 => array:2 [
"entity_id" => 486
"entity" => "user"
]
]
EXPECTED ARRAY:
array:2 [
0 => array:4 [
"id" => 931
"text" => "Test User 1"
"type" => "user"
"children" => array:2 [
0 => array:3 [
"id" => 5
"text" => "Location 1"
"type" => "location"
]
1 => array:3 [
"id" => 932
"text" => "Test User 2"
"type" => "user"
]
]
]
1 => array:3 [
"id" => 486
"text" => "Test User 3"
"type" => "user"
]
]
I have created a recursive function for this job
public function getNewStructure($tree, &$output) {
foreach($tree as $data) {
$output[] = array(
'id' => $data['entity_id'],
'text' => $data['user'] === 'user' ? User::find($data['entity_id'])->name : Location::find($data['entity_id'])->name,
'type' => $data['entity']
);
$this->getNewStructure($data['children'] ?? [], $output);
}
return $output;
}
but it not returns as expected:
array:4 [
0 => array:3 [
"id" => 931
"text" => "Test User 1"
"type" => "user"
]
0 => array:3 [
"id" => 5
"text" => "Location 1"
"type" => "location"
]
1 => array:3 [
"id" => 932
"text" => "Test User 2"
"type" => "user"
]
1 => array:3 [
"id" => 486
"text" => "Test User 3"
"type" => "user"
]
]
How can I add the children to the $output array in the recursive function ???
I have tried by adding the children key:
$this->getNewStructure($data['children'] ?? [], $output['children']);
as when iterating again it will push the current array in the right place.... but is not working...

I fixed
public function getNewStructure($tree, &$output) {
foreach($tree as $data) {
$element = array(
'id' => $data['entity_id'],
'text' => $data['user'] === 'user' ? User::find($data['entity_id'])->name : Location::find($data['entity_id'])->name,
'type' => $data['entity']
);
if(is_array($data['children']) && count($data['children']) > 0) {
$element['children'] = $this->getNewStructure($data['children'], $element['children']);
}
$output[] = $element;
}
return $output;
}

Related

Not able to group inner array of the multi-dimensional array

I have an array like this & I need to group an array based on value.
array:3 [
0 => array:5 [
"id" => 1
"maxView" => 0
"maxClick" => 20
"companyName" => "Project A"
"email" => "user1#email.com"
]
1 => array:5 [
"id" => 1
"maxView" => 0
"maxClick" => 20
"companyName" => "Project A"
"email" => "user2#email.com"
]
2 => array:5 [
"id" => 1
"maxView" => 0
"maxClick" => 20
"companyName" => "Project A"
"email" => "user3#email.com"
]
3 => array:5 [
"id" => 1
"maxView" => 0
"maxClick" => 20
"companyName" => "Project B"
"email" => "user1#email.com"
]
4 => array:5 [
"id" => 1
"maxView" => 0
"maxClick" => 20
"companyName" => "Project B"
"email" => "user6#email.com"
]
]
So far, I have following lines of codes. This is grouping my array based on fieldName = companyName But I am not able to add emails belonging to companyname under an array.
foreach ($records as $record) {
if (!array_key_exists($record[$fieldName], $groupedArray)) {
$groupedArray[$record[$fieldName]] = [];
}
$groupedArray[$record[$fieldName]] = $record;
$groupedArray[$record[$fieldName]]['email'] = [];
if (!in_array($record['email'], $groupedArray[$record[$fieldName]]['email'], true)) {
$groupedArray[$record[$fieldName]]['email'][] = $record['email'];
}
}
My code is adding only last email to the array.
"Project A" => [
....
"email" => array:1 [
0 => "user3#email.com"
]
Can anybody help me what I am missing here ?

Transform Laravel collection and group by key

I would like to transform a collection of object in laravel, but I can't figure it out how. I want to group the record by the type column, and set the grouped record under an array key value.
public function transformData()
{
$data = collect();
$matches = [ 'race', 'ethnicity'];
$attributes = Attribute::withTrashed()
->whereIn('type', $matches)
->get()
->groupBy('type');
$data->put(
$type, // to be the group key(like race)
[
'values' => $attributes->toArray(), // to be all the value with type race
]
);
dd(collect($data));
}
Here is what I'm getting:
Illuminate\Support\Collection^ {#2368
#items: array:1 [
"values" => array:2 [
"ethnicity" => array:2 [
0 => array:2 [
"id" => 1
"type" => "ethnicity"
]
1 => array:2 [
"id" => 2
"type" => "ethnicity"
]
]
"race" => array:2 [
0 => array:2 [
"id" => 6
"type" => "race"
]
1 => array:2 [
"id" => 7
"type" => "race"
]
]
]
]
#escapeWhenCastingToString: false
}
BUT I would like to return this instead:
Illuminate\Support\Collection^ {#2368
#items: array:1 [
"ethnicity" => array:2 [
"value" => array:2 [
0 => array:2 [
"id" => 1
"type" => "ethnicity"
]
1 => array:2 [
"id" => 2
"type" => "ethnicity"
]
]
]
"race" => array:2 [
"value" =>
0 => array:2 [
"id" => 6
"type" => "race"
]
1 => array:2 [
"id" => 7
"type" => "race"
]
]
]
#escapeWhenCastingToString: false
}

Complicated Where query in Laravel/MongoDB

I have an array(or collection) like this for my notifications. Each notification has an array field for all users who has seen the notification.
array:2 [
0 => array:8 [
"_id" => "604485ddf92e0000050079c6"
"title" => "Notification title"
"message" => "Notification message"
"type" => "success"
"expire_date" => "2021-05-09T19:30:00.000000Z"
"read_by_users" => array:2 [
0 => array:2 [
"user_id" => "601fd68d212200006f001c0b"
"seen_time" => 1615103466
]
1 => array:2 [
"user_id" => "60365402546900008a007c76"
"seen_time" => "1615103466"
]
]
"updated_at" => "2021-03-07T07:50:53.314000Z"
"created_at" => "2021-03-07T07:50:53.314000Z"
]
1 => array:8 [
"_id" => "604497d2f92e0000050079c7"
"title" => "Next Notification title"
"message" => "Next Notification message"
"type" => "success"
"expire_date" => "2021-05-09T19:30:00.000000Z"
"read_by_users" => array:1 [
0 => array:2 [
"user_id" => "601fd68d212200006f001c0b"
"seen_time" => 1615187929
]
]
"updated_at" => "2021-03-07T09:07:30.066000Z"
"created_at" => "2021-03-07T09:07:30.066000Z"
]
]
Now I want to get notifications where has not seen by current user (for example with this user_id 60365402546900008a007c76).
Any solution would be apreciated 🙏.
My project is in Laravel 8 and MongoDB.
If you want the result using array here is a solution
$userId = '60365402546900008a007c76'; $notifications = [];
foreach ($data as $notification) {
$userIds = array_column($notification['read_by_users'], 'user_id');
if (!in_array($userId, $userIds)) {
$notifications [] = $notification;
}
dd($notifications);

How to get value from unserialized data

I'm transforming my data into an array structure. Now I have the meta which already unserialized and I just need to take a specific value in meta.
Code
$item->meta;
$itm['attrs'] = #unserialize($item->meta);
$serial = #unserialize($item->meta);
$itm['product']['attrs'] = $itm['attrs'];
$itm['product']['serial'] = $serial['serial'];
Result
"product" => array:2 [
"attrs" => array:1 [
"serial" => array:1 [
0 => array:3 [
"id" => 848
"text" => "12345wf"
"trade_in" => 0
]
]
]
"serial" => array:1 [
0 => array:3 [
"id" => 848
"text" => "12345wf"
"trade_in" => 0
]
]
]
Expected Result
"product" => array:2 [
"attrs" => array:1 [
"serial" => array:1 [
0 => array:3 [
"id" => 848
"text" => "12345wf"
"trade_in" => 0
]
]
]
"serial" => "12345wf"
]
I'm not sure how to get the value and pass to the object.

php iterate multidimesional array with array_map

i have an array as below :
array:4 [
"tag" => "form"
"attr" => array:1 [
"class" => array:1 [
0 => "form-horizontal"
]
]
"text" => " "
"child" => array:1 [
0 => array:3 [
"tag" => "fieldset"
"text" => " "
"child" => array:1 [
0 => array:2 [
"tag" => "input"
"text" => "input name"
]
]
]
]
]
id like to recreate a new array as below
array[
0 => array[
"input" => "something",
"value" => "somevalue"
],
0 => array[
"input" => "something",
"value" => "somevalue"
]
]
if "tag" => "input"
currently am using below code , laravel based :
public function AjaxData(Request $request)
{
//
$array = $request->json;
debug($array);
$array2 = array_map(array($this, 'sanitize'), $test1 );
debug($array2);
return response()->json(['name' => $array['tag'] ]);
}
private function sanitize($value)
{
return $value['tag'];
}

Categories