Add an element to a multidimensional array - php

Add an element to a multidimensional array
Tell me how to make it so as to get an array of $params2 from the array $params
$params = [
'id' => 234223,
'price' => [
"currencyId" => "RUR",
"value" => 2000,
]
];
$params2 = [
'id' => 234223,
'price' => [
"currencyId" => "RUR",
"value" => 2000,
"discountBase" => 3000
]
];

You can assign it to a new variable $params2 then assign $params2['price']['discountBase'] = 3000;
For example:
$params = [
'id' => 234223,
'price' => [
"currencyId" => "RUR",
"value" => 2000,
]
];
$params2 = $params;
$params2['price']['discountBase'] = 3000;
var_export($params2);
Output:
array (
'id' => 234223,
'price' =>
array (
'currencyId' => 'RUR',
'value' => 2000,
'discountBase' => 3000,
),
)

Related

Array sum of selected dates from the array of rooms with set dates and prices

I've got an array of selected dates and an array of rooms with set dates and prices. From the array $selectedDates, it should look for a date from the rooms. If one of the $selectedDates is found from each room, it should use the price under the options keys if not it should use the default_price key.
$selectedDates = ['10-04-2022', '11-04-2022', '12-04-2022'];
$setRooms = [
0 => [
'id' => 1,
'title' => 'Room1',
'default_price' => 50,
'options' => [
0 => [
'date' => '12-04-2022',
'price' => 100,
],
1 => [
'date' => '13-04-2022',
'price' => 200,
],
3 => [
'date' => '14-04-2022',
'price' => 200,
],
]
],
1 => [
'id' => 2,
'title' => 'Room2',
'default_price' => 120,
'options' => [
0 => [
'date' => '11-04-2022',
'price' => 200,
],
1 => [
'date' => '12-04-2022',
'price' => 300,
],
3 => [
'date' => '13-04-2022',
'price' => 400,
],
]
],
]
Expected Output:
[
// '10-04-2022' = 50 (default_price), '11-04-2022' = 50 (default_price), '12-04-2022' = 100 (using the option price). 50 + 50 + 100 = 200
0 => [
'id' => 1,
'title' => 'Room1',
'total_price' => 200
],
// '10-04-2022' = 50 (default_price), '11-04-2022' = 200 (using the option price), '12-04-2022' = 300 (using the option price). 120 + 200 + 300 = 620
1 => [
'id' => 2,
'title' => 'Room2',
'total_price' => 620
]
]
This is what I've done so far. But it turns out that room 2 is giving me a different output, it's like the sum of room 1 will be added to room 2.
$price = 0;
$roomBookings = [];
foreach ($hotelRooms as $key => $room) {
$count = count($listOfSelectedDates);
foreach ($listOfSelectedDates as $selectedDate) {
$getPrice = HelperTrait::searchForDate($selectedDate, $room['options']);
if ($getPrice['success']) {
$price += $getPrice['price'];
}
else {
$price += $room['default_price'];
}
$room['total_price'] = $price;
}
$roomBookings[] = $room;
}
/////
public static function searchForDate($date, $array): array
{
foreach ($array as $key => $val) {
$date = Carbon::parse($date)->format('d-m-Y');
$arrDate = Carbon::parse($val['date'])->format('d-m-Y');
if ($arrDate === $date) {
return [
'success' => true,
'price' => $val['price']
];
}
}
return [
'success' => false
];
}
Let me know if you have any questions.
Thanks in advance!
$setRooms = [
[
'id' => 1,
'title' => 'Room1',
'default_price' => 50,
'options' => [
[ 'date' => '12-04-2022', 'price' => 100, ],
[ 'date' => '13-04-2022', 'price' => 200, ],
[ 'date' => '14-04-2022', 'price' => 200, ],
]
],
[
'id' => 2,
'title' => 'Room2',
'default_price' => 120,
'options' => [
[ 'date' => '11-04-2022', 'price' => 200, ],
[ 'date' => '12-04-2022', 'price' => 300, ],
[ 'date' => '13-04-2022', 'price' => 400, ],
]
],
];
$selectedDates = [ '10-04-2022', '11-04-2022', '12-04-2022' ];
$result = [];
foreach ($setRooms as $room) {
$total = 0;
foreach ($selectedDates as $date) {
$filtered = array_filter($room['options'], fn($option) => $date === $option['date']);
if (count($filtered) === 1) {
$total += $filtered[array_key_first($filtered)]['price'];
} else {
$total += $room['default_price'];
}
}
$result[] = [ 'id' => $room['id'], 'title' => $room['title'], 'total_price' => $total ];
}
print_r($result);
Output:
Array
(
[0] => Array
(
[id] => 1
[title] => Room1
[total_price] => 200
)
[1] => Array
(
[id] => 2
[title] => Room2
[total_price] => 620
)
)

Restructure multidimensional array based on associative array key

I have the following array:
$products = [
[
'id' => 21,
'name' => 'Floral Dress',
'params' => [
'size' => 14,
'price' => 23.99,
'department' => 'Dresses'
]
],
[
'id' => 413,
'name' => 'Maxi Skirt',
'params' => [
'size' => 10,
'price' => 12.99,
'department' => 'Skirts'
]
],
[
'id' => 78,
'name' => 'A Line Prom Dress',
'params' => [
'size' => 10,
'price' => 79.99,
'department' => 'Dresses'
]
],
[
'id' => 212,
'name' => 'Nude Block High Heels',
'params' => [
'size' => 6,
'price' => 20.99,
'department' => 'Shoes'
]
],
[
'id' => 54,
'name' => 'Denim Trim Dress',
'params' => [
'size' => 8,
'price' => 52.99,
'department' => 'Dresses'
]
],
];
Unfortunately I cannot control how the array is built.
Instead I need to restructure the data so that the array is sorted by the ['params']['department'] key.
So ideally I would take the above and output it like so:
$products = [
'Dresses' => [
[
'id' => 21,
'name' => 'Floral Dress',
'params' => [
'size' => 14,
'price' => 23.99
]
],
[
'id' => 78,
'name' => 'A Line Prom Dress',
'params' => [
'size' => 10,
'price' => 79.99
]
],
[
'id' => 54,
'name' => 'Denim Trim Dress',
'params' => [
'size' => 8,
'price' => 52.99
]
],
],
'Skirts' => [
[
'id' => 413,
'name' => 'Maxi Skirt',
'params' => [
'size' => 10,
'price' => 12.99
]
],
],
'Shoes' => [
[
'id' => 212,
'name' => 'Nude Block High Heels',
'params' => [
'size' => 6,
'price' => 20.99
]
],
]
You could simply iterate over all the products and populate a new associative array holding the departments, which are themselves arrays of corresponding products. See the comments in the code below.
<?php
// same data as in the question, just in one line for better overview
$products = [['id' => 21,'name' => 'Floral Dress','params' => ['size' => 14,'price' => 23.99,'department' => 'Dresses']],['id' => 413,'name' => 'Maxi Skirt','params' => ['size' => 10,'price' => 12.99,'department' => 'Skirts']],['id' => 78,'name' => 'A Line Prom Dress','params' => ['size' => 10,'price' => 79.99,'department' => 'Dresses']],['id' => 212,'name' => 'Nude Block High Heels','params' => ['size' => 6,'price' => 20.99,'department' => 'Shoes']],['id' => 54,'name' => 'Denim Trim Dress','params' => ['size' => 8,'price' => 52.99,'department' => 'Dresses']]];
// initialize empty department array
$departments = array();
// iterate over all the products
foreach ( $products as $product ) {
// get this product's department
$product_department = $product['params']['department'];
// unset the department in the params array
unset( $product['params']['department'] );
// initialize this department as an empty array
// if it doesn't exist yet
if ( !isset( $departments[$product_department] ) ) {
$departments[$product_department] = array();
}
// push this product in its corresponding department
$departments[$product_department][] = $product;
}
var_dump( $departments );
$groupedProducts = [];
foreach ($products as &$product) {
$department = $product['params']['department'];
unset($product['params']['department']);
$groupedProducts[$department] = $product;
}
var_dump($groupedProducts);

Sort multi-dimensional array so specific sub-array is first

I want to sort an array so that a specific array with a specific value is shown as the first in the array.
The array I have:
array = [
[0] => [
'id' => 123,
'name' => 'Random'
],
[1] => [
'id' => 156,
'name' => 'keyboard'
],
[2] => [
'id' => 12235,
'name' => 'Text'
],
];
I want the sub-array where the name is 'keyboard' to be the first in line of the big array.
Does anyone have suggestions?
usort Sort an array by values using a user-defined comparison function
$array = [
0 => [
'id' => 123,
'name' => 'Random'
],
1 => [
'id' => 156,
'name' => 'keyboard'
],
2 => [
'id' => 12235,
'name' => 'Text'
],
];
usort($array, function ($item) {
return $item['name'] != 'keyboard';
});
print_r($array);
See the demo
$myArray = [
[0] => [
'id' => 123,
'name' => 'Random'
],
[1] => [
'id' => 156,
'name' => 'keyboard'
],
[2] => [
'id' => 12235,
'name' => 'Text'
],
];
$temp = $myArray[0];
$myArray[0] = $myArray[1];
$myArray[1] = $temp;

How can run recursive function on multiple Level array in php

I have two arrays one is $apiRes and second is $mappData i want to match fields exist in mappData array and assign value of apiRes to match field.
Note: response of api may have different and mapdata array will change according to api response My two array and output format :
<?php
$apiRes = [
[
'firstname' => 'first name des',
'title' => "title des",
'category' => 1,
'result' =>
[
0 => [
'name' => 'Masterpass',
'skill' => 'low level one'
],
1 => [
'name' => 'Visa',
'skill' => 'low level two'
],
2 => [
'name' => 'Pocketpos',
'skill' => 'low level three'
],
],
'list' => [
'product_name'=>'product name',
'amount' => [
'currency'=>'$',
'kind' => 'kind'
]
],
'priority' => 'Low',
'visible_to' => 'Everyone',
]
];
$mappData = [
0 => [
"src_field" => "firstname",
"target_field" => "new1519110449758",
"src_field_data_type" => "string"
],
1 => [
"src_field" => "result.name",
"target_field" => "new1519110811942",
"src_field_data_type" => "string"
],
2 => [
"src_field" => "list.product_name",
"target_field" => "new1519110451708",
"src_field_data_type" => "string"
],
3 => [
"src_field" => "list.amount.currency",
"target_field" => "new1517556165360",
"src_field_data_type" => "string"
]
];
My final output should be:
$output = [
"new1519110449758" => "first name des",
"new1519110451708" => "product name",
"new1517556165360" => "$",
"new1519110811942" => [
0 => "Masterpass",
1 => "Visa",
2 => "Pocketpos"
]
];
Please help
Thanks
I've changed your mappData slightly as it's difficult to know how to deal with the result.name element as it's repeated. What I've done is change it so that it's *result.name and it uses the fact there is an * in it to mean there are multiple values.
I've tried to comment the code with enough to explain each bit, the main principle is using a recursive routine to go through each level of the array one step at a time.
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$apiRes = [
[
'firstname' => 'first name des',
'title' => "title des",
'category' => 1,
'result' =>
[
0 => [
'name' => 'Masterpass',
'skill' => 'low level one'
],
1 => [
'name' => 'Visa',
'skill' => 'low level two'
],
2 => [
'name' => 'Pocketpos',
'skill' => 'low level three'
],
],
'list' => [
'product_name'=>'product name',
'amount' => [
'currency'=>'$',
'kind' => 'kind'
]
],
'priority' => 'Low',
'visible_to' => 'Everyone',
]
];
$mappData = [
0 => [
"src_field" => "firstname",
"target_field" => "new1519110449758",
"src_field_data_type" => "string"
]
,
1 => [
"src_field" => "*result.name",
"target_field" => "new1519110811942",
"src_field_data_type" => "string"
],
2 => [
"src_field" => "list.product_name",
"target_field" => "new1519110451708",
"src_field_data_type" => "string"
],
3 => [
"src_field" => "list.amount.currency",
"target_field" => "new1517556165360",
"src_field_data_type" => "string"
]
];
$result = [];
// Process next element of the array
function getArrayElement ( $next, $data, $array = false ) {
// Extract key for this level
$key = array_shift($next);
// If starts with * then this means there are multiple of them
if ( $key[0] == "*" ){
$nextArray = true;
// remove from current key
$key = substr($key,1);
}
else {
$nextArray = false;
}
if ( $array ){
$res = [];
// extract the data from each element at this level
foreach ( $data as $read ) {
$res[] = $read[$key];
}
$data = $res;
}
else {
// Fetch the element for the key for this level
$data = $data [ $key ];
}
// If there are more levels to deal with then repeat this method
if ( count($next) > 0 ) {
$data = getArrayElement ( $next, $data, $nextArray );
}
return $data;
}
// Flatten out original array if necessary
if ( count($apiRes) == 1 ){
$apiRes = $apiRes[0];
}
// Process each part of lookup
foreach ( $mappData as $element ) {
// Create an array of the elments broken down into each level
$map = explode( '.', $element['src_field']);
$result[$element['target_field']] = getArrayElement($map, $apiRes);
}
print_r($result);

Recursively Create an Array from another Array

I am trying to make a multi-dimensional array build an array path adding the hr field so it looks like this:
I just can't figure out how to add the totals, nor create a sub-array so the dot notation in an option too. My goal is to get something like this:
[1] => [1][2][1][5][0][6] = 35 (the second child path "1")
[1] => [1][2][1][5][0][7] = 25
or Something like this:
array (
[children.0.children.0.children.0.total] = 20
[children.0.children.1.children.1.total] = 35
// etc
)
The complicated part is that it goes in different directions and I want to know what is the highest and lowest total based on the path:
==> Run Code Here or Copy/Paste
// -------------
// The Flattener
// -------------
function doit($myArray) {
$iter = new RecursiveIteratorIterator(new RecursiveArrayIterator($myArray));
$result = array();
foreach ($iter as $leafKey => $leafValue) {
$keys = array();
foreach (range(0, $iter->getDepth()) as $depth) {
$keys[] = $iter->getSubIterator($depth)->key();
}
$result[ join('.', $keys) ] = $leafValue;
}
return $result;
}
// -------------
// Example Tree
// -------------
$tree = [
'id' => 1,
'type' => 'note',
'data' => [],
'children' => [
[
'id' => 2,
'type' => 'wait',
'data' => [
'hr' => 10,
],
'children' => [
[
'id' => 3,
'type' => 'wait',
'data' => [
'hr' => 10,
],
'children' => [
'id' => 4,
'type' => 'exit',
'data' => [],
'children' => []
]
],
[
'id' => 5,
'type' => 'note',
'data' => [
'hr' => 10,
],
'children' => [
[
'id' => 6,
'type' => 'wait',
'data' => [
'hr' => 10,
],
'children' => []
],
[
'id' => 7,
'type' => 'exit',
'data' => [],
'children' => []
],
]
]
],
]
]
];
$result = doit($tree);
print_r($result);
This seems to work, I found it somewhere googling all day.
array_reduce(array_reverse($keys), function($parent_array, $key) {
return $parent_array ? [$key => $parent_array] : [$key];
}, null);

Categories