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

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 ?

Related

recursive function transform nested array

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;
}

Yii2 select2 selected one value 2 and more time

I have select2
return $this->form->field($this->model, 'observers')
->widget(Select2::className(),
[
'data' => Tasks::getAllStaffsGroupOffice(),
'disabled' => !$this->can['changeObservers'],
'options' => [
'multiple' => true,
'value' => ArrayHelper::map($this->model->observers, 'staff_id', 'staff_id'),
'placeholder' => Yii::t('tasks_forms', 'FORM_PLACEHOLDER_CHOOSE'),
'class' => 'hiddenInput'
],
'pluginOptions' => [
'allowClear' => true,
'closeOnSelect'=> false,
],
'pluginLoading' => false,
]);
Tasks::getAllStaffsGroupOffice() geting users array by offices. Example ->
array:4 [▼
"main office" => array:1 [▼
2 => "123 123"
]
"office 1" => array:3 [▼
3 => "staff_1"
6 => "staff_2"
2 => "123 123"
]
"office 3" => array:2 [▼
4 => "staff_3"
3 => "staff_1"
]
"office 2" => array:2 [▼
5 => "staff_4"
3 => "staff_1"
]
]
select2 value example -> array (2 => "2")
As a result, the display of the widget itself looks like this
select2 value
How to make it so that the staff which is in 2 and more offices is displayed only 1 time?
I believe you should filter your staff list and then pass it to Select2 widget. My approach for creating a unique array of staff is like this:
$allStaffsGroupOffice = [
"main office" => [
2 => "123 123"
],
"office 1" => [
3 => "staff_1",
6 => "staff_2",
2 => "123 123"
],
"office 3" => [
4 => "staff_3",
3 => "staff_1"
],
"office 2" => [
5 => "staff_4",
3 => "staff_1"
]
];
$repeatedStaff = [];
$newUniqueList = [];
foreach ($allStaffsGroupOffice as $office => $staffList) {
foreach ($staffList as $staffId => $staffName) {
if (!in_array($staffId, $repeatedStaff)) {
$repeatedStaff[] = $staffId;
$newUniqueList[$office][$staffId] = $staffName;
}
}
}
$newUniqueList will be your new array which contains offices with unique staff.

How to get required data from this array

I am using Laravel. I have a complex array and i want to make it more readable and I am not sure how to convert it into more readable form and i want to pass only the required information. this is loop
foreach($dataArray as $value){
$addressArray[] = [
'id' => $value['place_id'],
'address'=> $value['terms'],
];
}
dd($addressArray);
}
and this array returns response in following format and I want to format this array
array:5 [
0 => array:4 [
"id" => "ChIJH6WK3tQ0K4gRm0XKDAjRGfA"
"label" => "12 York Street, Toronto, ON, Canada"
"value" => "12 York Street, Toronto, ON, Canada"
"address" => array:5 [
0 => array:2 [
"offset" => 0
"value" => "12"
]
1 => array:2 [
"offset" => 3
"value" => "York Street"
]
2 => array:2 [
"offset" => 16
"value" => "Toronto"
]
3 => array:2 [
"offset" => 25
"value" => "ON"
]
4 => array:2 [
"offset" => 29
"value" => "Canada"
]
]
]
]
2 => array:4 [
"id" => "ChIJJa4u6nqipBIRthG2uMmbv2M"
"label" => "Avinguda de Rius i Taulet, 12, Barcelona, Spain"
"value" => "Avinguda de Rius i Taulet, 12, Barcelona, Spain"
"address" => array:4 [
0 => array:2 [
"offset" => 0
"value" => "Avinguda de Rius i Taulet"
]
1 => array:2 [
"offset" => 27
"value" => "12"
]
2 => array:2 [
"offset" => 31
"value" => "Barcelona"
]
3 => array:2 [
"offset" => 42
"value" => "Spain"
]
]
]
3 => array:4 [
"id" => "ChIJUXFxe6qMwokRT2J7mbHQE3o"
"label" => "1250 Waters Place, Bronx, NY, USA"
"value" => "1250 Waters Place, Bronx, NY, USA"
"address" => array:5 [
0 => array:2 [
"offset" => 0
"value" => "1250"
]
1 => array:2 [
"offset" => 5
"value" => "Waters Place"
]
2 => array:2 [
"offset" => 19
"value" => "Bronx"
]
3 => array:2 [
"offset" => 26
"value" => "NY"
]
4 => array:2 [
"offset" => 30
"value" => "USA"
]
]
]
4 => array:4 [
"id" => "ChIJfz6STcJYwokRFONBxt9Ytvs"
"label" => "1275 York Avenue, New York, NY, USA"
"value" => "1275 York Avenue, New York, NY, USA"
"address" => array:5 [
0 => array:2 [
"offset" => 0
"value" => "1275"
]
1 => array:2 [
"offset" => 5
"value" => "York Avenue"
]
2 => array:2 [
"offset" => 18
"value" => "New York"
]
3 => array:2 [
"offset" => 28
"value" => "NY"
]
4 => array:2 [
"offset" => 32
"value" => "USA"
]
]
]
]
However I want to format data in this format.
array:5 [
0 => array:4 [
"id" => "ChIJH6WK3tQ0K4gRm0XKDAjRGfA"
"label" => "12 York Street, Toronto, ON, Canada"
"value" => "12 York Street, Toronto, ON, Canada"
"address" => [
'number' => 12,//from address array, index 0 value
'street'=>'York Street',//from address array, index 1 value
'city'=>'Tornonto,//from address array, index 2 value
'state=>'ON',//from address array, index 3 value
'country'=>'Canada'//from address array, index 4 value
];
}
Any help? Thanks
You can set the value by referencing each index of the terms key manually
$number = '';
$street = '';
$city = '';
$state = '';
$country = '';
if (isset($value['terms'][0]['value']))
$number = $value['terms'][0]['value'];
if (isset($value['terms'][1]['value']))
$street = $value['terms'][1]['value'];
if (isset($value['terms'][2]['value']))
$city = $value['terms'][2]['value'];
if (isset($value['terms'][3]['value']))
$state = $value['terms'][3]['value'];
if (isset($value['terms'][4]['value']))
$country = $value['terms'][4]['value'];
$addressArray[] = [
'id' => $value['place_id'],
'label' => $value['description'],
'value' => $value['description'],
'address' => [
'number' => $number,
'street' => $street,
'city' => $city,
'state' => $state,
'country' => $country
]
];

Laravel 8: Sorting grouped array by a nested column - what should I put into sortBy closure?

I'm dealing with a specifically shaped array in Laravel where items are grouped by keys that represent names of categories.
In below example I have elements from categories 1, 5 and 76. Each element has a key called order which is a nullable integer that should indicate the order within this category.
array:3 [
"category_1" => array:4 [
1 => array:2 [
"option_name" => "Some name 1"
"option_items" => array:1 [
0 => array:5 [
"id" => 1
"price" => 200
"time" => 0
"order" => 999
]
]
]
2 => array:2 [
"option_name" => "Some name 2"
"option_items" => array:1 [
0 => array:5 [
"id" => 2
"price" => 780
"time" => 5
"order" => null
]
]
]
3 => array:2 [
"option_name" => "Some name 3"
"option_items" => array:1 [
0 => array:5 [
"id" => 3
"price" => 400
"time" => 4
"order" => null
]
]
]
4 => array:2 [
"option_name" => "Some name 4"
"option_items" => array:1 [
0 => array:5 [
"id" => 4
"price" => 300
"time" => 2
"order" => 434
]
]
]
]
"category_5" => array:2 [
6 => array:2 [
"option_name" => "Some name 5"
"option_items" => array:1 [
0 => array:5 [
"id" => 6
"price" => 890
"time" => 3
"order" => null
]
]
]
7 => array:2 [
"option_name" => "Some name 6"
"option_items" => array:1 [
0 => array:5 [
"id" => 7
"price" => 1290
"time" => 5
"order" => null
]
]
]
]
"category_76" => array:2 [
10 => array:2 [
"option_name" => "Some name 7"
"option_items" => array:1 [
0 => array:5 [
"id" => 10
"price" => 320
"time" => 4
"order" => 33
]
]
]
11 => array:2 [
"option_name" => "Some name 8"
"option_items" => array:2 [
0 => array:5 [
"id" => 11
"price" => 600
"time" => 0
"order" => 500
]
1 => array:5 [
"id" => 12
"price" => 2000
"time" => 9
"order" => 500
]
]
]
]
]
I simply want to sort this entire array per category by order key ascending (with nulls at the end), so for example the order of elements in category_1 would be:
Some name 4 (order of 434)
Some name 1 (order of 999)
Some name 2 (order is nor present / null)
Some name 3 (same as above)
What did you try?
Obviously I've tried converting this plain PHP array to collection and calling sortBy with a closure via:
$sorted = collect($array)->sortBy(function ($elementsInCategory, $key) {
dd($elementsInCategory); // $key is category_1
})->toArray();
but I simply don't know what to return from the callback to make it sort the way I've described.
BTW. I don't want to complicate too much but please notice that option_items sub-array may sometimes have more than one item (key 11 from category_76) but this does not matter - elements in this sub array will always have the same order value. This inner array should not be sorted - can be left as is.
You can use Laravel collection macro for that
$Collection::macro('sortByOrder', function (string $column = 'order', bool $descending = false) {
/* #var $this Collection */
return $this->sortBy(function ($order) use ($column) {
return strtotime(((object)$order)->$column);
}, SORT_REGULAR, $descending);
});
And you can use it like
$categories->sortByOrder('order',false);

how to remove a parent index array and change it to object in laravel

I have an array like below :
array:3 [
"2021-08-07" => array:3 [
"id" => "1"
"date" => "2021-08-07"
"numbers" => array:2 [
0 => 1
1 => 2
]
]
"2021-08-08" => array:3 [
"id" => "1"
"date" => "2021-08-08"
"numbers" => array:2 [
0 => 1
1 => 2
]
]
]
What I want to do is simply to remote the parent 2021-08-08 items because I have the date inside the array already . Now, what I have tried so far is :
$result = array_map(function ($el){
return $el[0];
},$test);
dd($result);
But it gives me error of undefined index[0] . what I want this array to look like is like below :
array:3 [
"id" => "1"
"date" => "2021-08-07"
"numbers" => array:2 [
0 => 1
1 => 2
],
"id" => "1"
"date" => "2021-08-08"
"numbers" => array:2 [
0 => 1
1 => 2
]
]
Won't just array_values() do?
array_values($test);
$test = array_values(yourArray);
$test = (object)$yourArray;

Categories