PHP - create date range array with values from multi array key search - php

I have multi array created from previous search. Point of this is enable hotel reservation in case hotel is full and quests must change room during stay. So array $freeRooms is created as array of free room by dates.
$freeRooms = array(
0 => array
(
'2020-07-23' => 37
),
1 => array
(
'2020-07-20' => 38,
'2020-07-21' => 38,
'2020-07-22' => 38
),
2 => array
(
'2020-07-25' => 38,
'2020-07-26' => 38
),
2 => array
(
'2020-07-20' => 59,
'2020-07-21' => 59
),
3 => array
(
'2020-07-20' => 86,
'2020-07-21' => 86
),
4 => array
(
'2020-07-20' => 39,
'2020-07-21' => 39
),
5 => array
(
'2020-07-25' => 39,
'2020-07-26' => 39
),
6 => array
(
'2020-07-20' => 40
),
7 => array
(
'2020-07-24' => 40,
'2020-07-25' => 40,
'2020-07-26' => 40
),
8 => array
(
'2020-07-20' => 41,
'2020-07-21' => 41,
'2020-07-22' => 41,
'2020-07-23' => 41
));
Second array is date range:
$dateRange = array(0 => '2020-07-20',
1 => '2020-07-21',
2 => '2020-07-22',
3 => '2020-07-23',
4 => '2020-07-24',
5 => '2020-07-25',
6 => '2020-07-26');
I need create some final array for every day from $dateRange use some rooms from $freeRooms. Point is to use as minimal id rooms as possible to get something like this:
$finalArray = array('2020-07-20' => 41,
'2020-07-21' => 41,
'2020-07-22' => 41,
'2020-07-23' => 41,
'2020-07-24' => 40,
'2020-07-25' => 40,
'2020-07-26' => 40);

This is my actual solution:
order by count of free days
array_multisort(array_map('count', $freeRooms), SORT_DESC, $freeRooms);
set $dateRange keys same as values
$newRange = array_combine($dateRange, $dateRange);
$finalRms = array();
loop and create new array
foreach($ffa as $k => $v) {
foreach($newRange as $nk => $nv) {
if(array_key_exists($nk, $v) && array_key_exists($nk, $finalRms) == false) {
$finalRms[$nk] = $v[$nk];
}
}
}

Related

PHP array with dynamic index

I tried to make table from PHP array. But here all key are dynamic and have also child array
Here is the array structure:
array (
1371618448317 =>
array (
0 =>
array (
0 => '23.77311734',
1 => '90.396355125',
2 => '23.77313316',
3 => '90.396411867187',
4 => '23.77309048',
5 => '90.396419484375',
6 => '23.77307348',
7 => '90.3963645',
),
1 => 20911,
2 =>
array (
1371618713208 =>
array (
0 => 1,
1 => 'BRAC Delivery Centre',
2 => '371/A Shahinbag',
3 => 25,
4 => 91,
5 => 221,
6 => 1,
7 => 11,
8 => 1,
9 => 99,
10 => 1,
11 => 99,
12 => 99,
13 => 99,
14 => 99,
15 => 99,
16 => 1,
),
),
),
1371619410448 =>
array (
0 =>
array (
0 => '23.77894566',
1 => '90.39968559375',
2 => '23.77916362',
3 => '90.400307765625',
4 => '23.77889887',
5 => '90.400401515625',
6 => '23.77870083',
7 => '90.399780515625',
),
1 => 24612,
2 =>
array (
1371619950162 =>
array (
0 => 1,
1 => 'EPI Centre (Govt.)',
2 => ' Mohakhali Road Mohakhali',
3 => 20,
4 => 91,
5 => 11,
6 => 1,
7 => 12,
8 => 1,
9 => 99,
10 => 1,
11 => 99,
12 => 99,
13 => 99,
14 => 99,
15 => 99,
16 => 0,
),
),
),
1371621080807 =>
array (
0 =>
array (
0 => '23.77746206',
1 => '90.399232078125',
2 => '23.77744917',
3 => '90.399623390625',
4 => '23.77712934',
5 => '90.39958940625',
6 => '23.77714809',
7 => '90.399205125',
),
1 => 24566,
2 =>
array (
1371621897771 =>
array (
0 => 1,
1 => 'Society for Assistance to Hearing Impaired Children (SAHIC)',
2 => 'N/A Sattola Road Mohakhali',
3 => 20,
4 => 91,
5 => 222,
6 => 1,
7 => 7,
8 => 1,
9 => 1,
10 => 1,
11 => 1,
12 => 99,
13 => 99,
14 => 99,
15 => 1,
16 => 0,
),
),
),
1371622305777 =>
array (
0 =>
array (
0 => '23.77357261',
1 => '90.36189965625',
2 => '23.77359605',
3 => '90.36197925',
4 => '23.77344028',
5 => '90.36201675',
6 => '23.77341802',
7 => '90.361931296875',
),
1 => 1325,
2 =>
array (
1371622497359 =>
array (
0 => 1,
1 => 'Natoinal Health Care Network',
2 => '3/Ka Pisiculture Housing Society Shamoly',
3 => 29,
4 => 91,
5 => 222,
6 => 1,
7 => 7,
8 => 1,
9 => 99,
10 => 99,
11 => 1,
12 => 99,
13 => 99,
14 => 1,
15 => 1,
16 => 0,
),
),
)
My Desire tale will be look like:
BRAC Delivery Centre 371/A Shahinbag 23.77311734 90.396355125
EPI Centre (Govt.) Mohakhali Road 23.77746206 90.399232078125
from lat long array I always try to collect first lat long.
Can any one give me solution ?
Here is your solution
Input
$array = array(
1371618448317 => array (
array ('23.77311734','90.396355125','23.77313316','90.396411867187','23.77309048','90.396419484375','23.77307348','90.3963645'),
20911,
array ('1371618713208' => array (1,'BRAC Delivery Centre','371/A Shahinbag',25,91,221,1,11,1,99,1,99,99,99,99,99,1))
),
1371619410448 => array (
array ('23.77894566','90.39968559375','23.77916362','90.400307765625','23.77889887','90.400401515625','23.77870083','90.399780515625',),
24612,
array ('1371619950162' => array (1,'EPI Centre (Govt.)',' Mohakhali Road Mohakhali',20,91,11,1,12,1,99,1,99,99,99,99,99,0))
),
1371621080807 => array(
array ('23.77746206','90.399232078125','23.77744917','90.399623390625','23.77712934','90.39958940625','23.77714809','90.399205125'),
24566,
array ('1371621897771' => array (1,
'Society for Assistance to Hearing Impaired Children (SAHIC)','N/A Sattola Road Mohakhali',20,91,222,1,7,1,1,1,1,99,99,99,1,0)
)
),
1371622305777 => array (
array ('23.77357261','90.36189965625','23.77359605','90.36197925','23.77344028','90.36201675','23.77341802','90.361931296875'),
1325,
array ('1371622497359' => array (1,
'Natoinal Health Care Network','3/Ka Pisiculture Housing Society Shamoly',29,91,222,1,7,1,99,99,1,99,99,1,1,0)
)
)
);
Solution
Coordinates are in 1st array.
Name and address is in 3rd.
Coordinates picks easily by $row[0][0].','.$row[0][1]; in given loop below.
For address and name you need to pick key of 3rd array, for this here I used $row[2][key($row[2]);
Now check the code below.
$new_array = array();
$i=0;
foreach($array as $key => $row){
//echo "<pre>";print_r(key($row[2]));
$new[$i]['coordinates'] = $row[0][0].','.$row[0][1];
$new[$i]['name'] = $row[2][key($row[2])][1];
$new[$i]['address'] = $row[2][key($row[2])][2];
$i++;
}
echo "<pre>";print_r($new);
Output
Array
(
[0] => Array
(
[coordinates] => 23.77311734,90.396355125
[name] => BRAC Delivery Centre
[address] => 371/A Shahinbag
)
[1] => Array
(
[coordinates] => 23.77894566,90.39968559375
[name] => EPI Centre (Govt.)
[address] => Mohakhali Road Mohakhali
)
[2] => Array
(
[coordinates] => 23.77746206,90.399232078125
[name] => Society for Assistance to Hearing Impaired Children (SAHIC)
[address] => N/A Sattola Road Mohakhali
)
[3] => Array
(
[coordinates] => 23.77357261,90.36189965625
[name] => Natoinal Health Care Network
[address] => 3/Ka Pisiculture Housing Society Shamoly
)
)
solved myself:
$assoc = true;
$result = json_decode ($json, $assoc);
echo "<table border='1'>";
echo "<tr><td>Hospital Name</td><td>Address</td><td>Lat1</td><td>Long1</td><td>Lat2</td><td>Long1</td><td>Lat3</td><td>Long3</td><td>Lat4</td><td>Long4</td></tr>";
foreach($result as $single_res){
$lat1 = $single_res[0][0];
$long1 = $single_res[0][1];
$lat2 = $single_res[0][2];
$long2 = $single_res[0][3];
$lat3 = $single_res[0][4];
$long3 = $single_res[0][5];
$lat4 = $single_res[0][6];
$long4 = $single_res[0][7];
$key = $single_res[2];
$key_val = array_keys($key);
$key_val = $key_val[0];
$name = $key[$key_val][1];
$address = $key[$key_val][2];

Sort array by mutiple fields (closest to number)

How can I sort a array by two(one) different values?
So I have a array like this:
array(
array(
'id' => 10,
'total' => 38,
'entry' => 400
),
array(
'id' => 4,
'total' => 34,
'entry' => 3100
),
array(
'id' => 2,
'total' => 34,
'entry' => 3150
),
array(
'id' => 8,
'total' => 34,
'entry' => 2980
),
);
The array is already sorted by the key total, but they all have the same value in total. So I need to sort by who is closest to 3000 by entry.
Edit
The array should be first sorted by total and then entry, since entry is only there so I can differentiate who is the best.
So the array should look like this:
array(
array(
'id' => 10,
'total' => 38,
'entry' => 400
),
array(
'id' => 8,
'total' => 34,
'entry' => 2980
),
array(
'id' => 4,
'total' => 34,
'entry' => 3100
),
array(
'id' => 2,
'total' => 34,
'entry' => 3150
)
);
Try this:
usort($arr, function ($a, $b) {
if ($a['total'] == $b['total']) { // Only compare on entry when the totals are the same.
return abs($a['entry'] - 3000) > abs($b['entry'] - 3000);
}
return $a['total'] < $b['total'];
});
print_r($arr);
Output:
Array
(
[0] => Array
(
[id] => 2
[total] => 35
[entry] => 3150
)
[1] => Array
(
[id] => 8
[total] => 34
[entry] => 2980
)
[2] => Array
(
[id] => 4
[total] => 34
[entry] => 3100
)
[3] => Array
(
[id] => 6
[total] => 34
[entry] => 3250
)
[4] => Array
(
[id] => 3
[total] => 32
[entry] => 3400
)
)
Here's how it works: it compares the totals, but if they're the same, it compares the absolute value of the difference between entry and 3000 of both entrys.
eval.in demo

PHP Multidimensional Array Sort & Trim

I have the array below. I do not know how I can sort secondary array so elements with highest value gets to be first and I want to trim if the array length is more than 20 elements. I want first dimension to be sorted by alphabetical, secondary dimension to be sorted by values and if there are more than 20 entries, I want only first 20 highest value.
(
[a] => Array
(
[option1] => 2
[option2] => 3
[option3] => 1
[option4] => 7
[option5] => 8
[option6] => 3
[option7] => 2
[option8] => 32
[option9] => 35
[option10] => 33
[option11] => 32
[option12] => 35
[option13] => 37
[option14] => 3
[option15] => 39
[option16] => 4
[option17] => 36
[option18] => 31
[option19] => 12
[option20] => 35
[option21] => 3
[option22] => 32
[option23] => 31
)
[b] => Array
(
[option16] => 4
[option17] => 36
[option18] => 31
[option19] => 12
)
Php has everything for you!
<?php
$array = array(
'b' => array(
'option1' => 33,
'option2' => 12,
'option3' => 17,
'option4' => 44,
'option5' => 543,
'option6' => 56,
'option7' => 8,
'option8' => 0,
'option9' => -10,
'option10' => 234,
'option11' => 67,
'option12' => 99,
'option13' => 3363,
'option14' => 912,
'option15' => 51,
'option16' => 42,
'option17' => 105,
'option18' => 80,
'option19' => 44,
'option20' => 0,
'option21' => 15,
),
'a' => array(
'option1' => 88,
'option2' => 0,
'option3' => -23,
'option4' => 16,
'option5' => 76,
),
);
// sorts array keys alphabetically
ksort($array, SORT_NATURAL);
// iterrate each key (a or b etc.) => value (value is assoc array of options) pair
foreach ($array as $k => &$v) {
// reverse sort (from max to min) options by its value
// with preserve keys
arsort($v);
// cut options array to max 20 element
$v = array_slice($v, 0, 20);
}
echo '<pre>' . print_r($array, 1) . '</pre>';
Online runnable.

Summing The Contents Of A Three Tiered Array PHP

This is the array I am using (3 tiers), and I am trying to add the number of sales (nosales) from the first month in the first array to the first month in the second array (Should be 150) and so on through all the variables (months shouldn't be added) so I am left with a two level array with the nosales, salevalue,salecost and saleprofit totals for each month.
Array (
[0] => Array
(
[1] => Array
(
[month] => 1
[nosales] => 100
[salevalue] => 1200
[salecost] => 360
[saleprofit] => 840
)
[2] => Array
(
[month] => 2
[nosales] => 110
[salevalue] => 1320
[salecost] => 396
[saleprofit] => 924
)
)
[1] => Array
(
[1] => Array
(
[month] => 1
[nosales] => 50
[salevalue] => 350
[salecost] => 70
[saleprofit] => 280
)
[2] => Array
(
[month] => 2
[nosales] => 55
[salevalue] => 385
[salecost] => 77
[saleprofit] => 308
)
)
)
Now, I have tried looping through them to get them to add together but I am getting a number of errors. Could someone please help?
Here is the script I am using at the moment:
$acc = array_shift($results_array);
foreach ($results_array as $val) {
foreach ($val as $v) {
foreach ($v as $key => $v){
$acc[$key] += $v;
}
}
}
Thanks for your help in advance!
Is this what you wanted to do?
$aResultsArray = array(
0 => array(
1 => array(
'month' => 1,
'nosales' => 100,
'salevalue' => 1200,
'saleconst' => 360,
'saleprofit' => 840,
),
2 => array(
'month' => 2,
'nosales' => 110,
'salevalue' => 1320,
'saleconst' => 396,
'saleprofit' => 924,
),
),
1 => array(
1 => array(
'month' => 1,
'nosales' => 50,
'salevalue' => 350,
'saleconst' => 70,
'saleprofit' => 280,
),
2 => array(
'month' => 2,
'nosales' => 55,
'salevalue' => 385,
'saleconst' => 77,
'saleprofit' => 308,
),
),
);
$aSum = array();
foreach ($aResultsArray as $mYear => $aMonths) {
foreach ($aMonths as $mMonth => $aMonth) {
if (!isset($aSum[$aMonth['month']])) {
$aSum[$aMonth['month']] = array(
'month' => $aMonth['month'],
'nosales' => 0,
'salevalue' => 0,
'saleconst' => 0,
'saleprofit' => 0,
);
}
$aSum[$aMonth['month']]['nosales'] += $aMonth['nosales'];
$aSum[$aMonth['month']]['salevalue'] += $aMonth['salevalue'];
$aSum[$aMonth['month']]['saleconst'] += $aMonth['saleconst'];
$aSum[$aMonth['month']]['saleprofit'] += $aMonth['saleprofit'];
}
}
var_dump($aSum);

PHP array_multisort not sorting my multidimensional array as expected

I am trying to sort a multidimensional array using the array_multisort function
I was expecting the multidimensional array to order itself using the values in $sort.
$sort relates to the volume element of my multidimensional array.
I would like the name element to be in this order:
'name' => 8, 'name' => 6, 'name' => 7, 'name' => 9', 'name' => 10, 'name' => 10,
The returned order is not as expected. Perhaps I have misunderstood how array_multisort works?
Array
(
[test1] => Array
(
[volume] => 67
[edition] => 2
[name] => 6
[num] => 2
)
[test2] => Array
(
[volume] => 86
[edition] => 1
[name] => 7
[type] => 2
)
[test3] => Array
(
[volume] => 85
[edition] => 6
[name] => 8
[type] => 2
)
[test4] => Array
(
[volume] => 98
[edition] => 2
[name] => 9
[type] => 2
)
[test5] => Array
(
[volume] => 86
[edition] => 6
[name] => 10
[type] => 2
)
[test6] => Array
(
[volume] => 67
[edition] => 7
[name] => 11
[type] => 2
)
)
$sort = array(85, 67, 86, 98, 86, 67);
array_multisort($sort, $data);
Here is the original array:
$data['test1'] = array('volume' => 67, 'edition' => 2, 'name' => 6, 'num' => 2,);
$data['test2'] = array('volume' => 86, 'edition' => 1, 'name' => 7, 'type' => 2,);
$data['test3'] = array('volume' => 85, 'edition' => 6, 'name' => 8, 'type' => 2,);
$data['test4'] = array('volume' => 98, 'edition' => 2, 'name' => 9, 'type' => 2,);
$data['test5'] = array('volume' => 86, 'edition' => 6, 'name' => 10, 'type' => 2,);
$data['test6'] = array('volume' => 67, 'edition' => 7, 'name' => 11, 'type' => 2,);
With array Multisort, you can Sort depending on a column. This is a example, where you can easily sort by "all" available columns:
<?
$data['test1'] = array('volume' => 67, 'edition' => 2, 'name' => 6, 'type' => 2);
$data['test2'] = array('volume' => 86, 'edition' => 1, 'name' => 7, 'type' => 2);
$data['test3'] = array('volume' => 85, 'edition' => 6, 'name' => 8, 'type' => 2);
$data['test4'] = array('volume' => 98, 'edition' => 2, 'name' => 9, 'type' => 2);
$data['test5'] = array('volume' => 86, 'edition' => 6, 'name' => 10, 'type' => 2);
$data['test6'] = array('volume' => 67, 'edition' => 7, 'name' => 11, 'type' => 2);
//Create index rows
foreach ($data as $row) {
foreach ($row as $key => $value){
${$key}[] = $value; //Creates $volume, $edition, $name and $type arrays.
}
}
//ex: sort by edition asc, then by name DESC:
array_multisort($edition, SORT_ASC, $name, SORT_DESC, $data);
echo "<pre>";
print_r($data);
echo "</pre>";
?>
will result in (first by edition ASC, then by name DESC):
(sorting by name ASC, will swap test4 and test1 ofc.)
Array
(
[test2] => Array
(
[volume] => 86
[edition] => 1
[name] => 7
[type] => 2
)
[test4] => Array
(
[volume] => 98
[edition] => 2
[name] => 9
[type] => 2
)
[test1] => Array
(
[volume] => 67
[edition] => 2
[name] => 6
[type] => 2
)
[test5] => Array
(
[volume] => 86
[edition] => 6
[name] => 10
[type] => 2
)
[test3] => Array
(
[volume] => 85
[edition] => 6
[name] => 8
[type] => 2
)
[test6] => Array
(
[volume] => 67
[edition] => 7
[name] => 11
[type] => 2
)
)
You can add as many columns if you like. I hope this helps.
Edit: As to your question:
No, Array MultiSort is NOT for sorting arrays based on a predefined order. What array_multisort does is:
It Sorts an array by the given Condition (asc or desc) and moves entries in the other arrays relatively up or down, without violating the sorting of any other array.
basic example:
$letters = array("b","a","c");
$numbers = array(5,4,2);
calling array_multisort($letters,$numbers) will result in a,b,c and (a has moved up, b down) 4,5,2
if the example would be:
$letters = array("b","a","a");
$numbers = array(5,4,2);
first the same sorting will apply: (a,a,b -> 4,2,5), but then array_multisort notices, that it can swap the both as to sort 2 and 4. Final REsult: a,a,b -> 2,4,5
Back to your question:
To sort by a predefined order, you can do the following:
1.) Define your order, i.e. $order = array("a","z","b");
2.) Call uasort with a user function.
3.) Inside that sort function, use array flip and assoc access to get the actual position:
$items = array("a","b","z","a","z","z");
uasort($items, "sortByPredefinedOrder");
function sortByPredefinedOrder($leftItem, $rightItem){
$order = array("a","z","b","x"); //defined somewhere
$flipped = array_flip($order); //so we can access "position by value"
$leftPos = $flipped[$leftItem];
$rightPos = $flipped[$rightItem];
return $leftPos >= $rightPos;
}
print_r($items); //Array ( [0] => a [3] => a [2] => z [4] => z [5] => z [1] => b )
for your multidimensional Input, you can use
$leftPos = $flipped[$leftItem["volume"]];
$rightPos = $flipped[$rightItem["volume"]];
But ofc. this would require you to predict ALL values inside the predefined order Array and handle IndexOutOfBoundExceptions with appropriate return values.

Categories