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.
Related
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];
}
}
}
I need to transpose a multidimensional associative array into a multidimensional indexed array sorted against and an external associative key. In the example below, I need a way to get from the 'input' to the 'expected output'.
I've tried array_match(), array_intersect() but I think I'm missing something. There must be an elegant solution to this but I cannot figure it out.
//Input
$array = array(
array('Volvo' => 22, 'BMW' => 13, 'Saab' => 5, 'Land Rover' => 11),
array('Nissan' => 10, 'Saab' => 4),
array('Land Rover' => 22, 'BMW' => 9, 'Nissan' => 2, 'Ford' => 17)
//...
);
//Expected output
$array_cars = array( // sorted list of unique car names
0 => 'BMW',
1 => 'Ford',
2 => 'Land Rover',
3 => 'Nissan',
4 => 'Saab',
5 => 'Volvo'
//...
);
$compiled_data = array( // 2D matrix, columns: $array, rows: $array_car
array(0 => 13, 2 => 9), // 'BMW'
array(2 => 17), // 'Ford'
array(0 => 11, 2 => 22), // 'Land Rover'
array(1 => 10, 2 => 2), // 'Nissan'
array(0 => 5, 1 => 4), // 'Saab'
array(1 => 22) // 'Volvo'
//...
);
Probably the simplest thing is to just iterate over all the values, sorting them into a car indexed array. You can then use ksort to sort the data:
$output = array();
foreach ($array as $key => $a) {
foreach ($a as $car => $v) {
$output[$car][$key] = $v;
}
}
ksort($output);
$array_cars = array_keys($output);
$compiled_data = array_values($output);
var_export($array_cars);
var_export($compiled_data);
Output:
array (
0 => 'BMW',
1 => 'Ford',
2 => 'Land Rover',
3 => 'Nissan',
4 => 'Saab',
5 => 'Volvo',
)
array (
0 =>
array (
0 => 13,
2 => 9,
),
1 =>
array (
2 => 17,
),
2 =>
array (
0 => 11,
2 => 22,
),
3 =>
array (
1 => 10,
2 => 2,
),
4 =>
array (
0 => 5,
1 => 4,
),
5 =>
array (
0 => 22,
),
)
Demo on 3v4l.org
I have array1 like this:
[user2] => 27
[user3] => 30
[user4] => 33
[user5] => 36
[user6] => 39
[user10] => 39
[user12] => 42
Using second (helper, authority) array:
[user2] => 6
[user3] => 7
[user4] => 1
[user5] => 4
[user6] => 3
[user10] => 2
[user12] => 5
And I want to sort array1 like this
[user2] => 27
[user3] => 30
[user4] => 33
[user5] => 36
[user10] => 39 // user10 goes before user6
[user6] => 39
[user12] => 42
Algorithms is: When rows in array1 has same value, check authority array and reorder same value rows according it. The lower value, the higher (earlier) it goes in sorted array1 (user10 has value 2 in authority array and therefore it goes before user6 which has value 3 in authority array).
array1 is order of users based on vote of various senators. There is also "president of senate". When you have users with same results (user6 and user10) reorder them according the preference of "president".
Another possible input is:
$arr = [
"user7" => 15,
"user11" => 15,
"user4" => 30,
"user19" => 36,
"user10" => 39,
];
$helper = [
"user4" => 3,
"user7" => 2,
"user10" => 4,
"user11" => 1,
"user19" => 5,
];
while this is desired output
Array
(
[user11] => 15
[user7] => 15
[user4] => 30
[user19] => 36
[user10] => 39
)
One option is to use array_keys and array_flip to get order array. Use uksort to sort the array based on order
$arr = ....
$helper = ...
$order = array_flip(array_keys( $helper ));
uksort ( $arr , function( $a , $b ) use ( $order, $arr, $helper ) {
if ( $arr[$a] != $arr[$b] ) return $order[$a] - $order[$b];
return $helper[$a] - $helper[$b];
});
UPDATE:
$arr = [
"user7" => 15,
"user11" => 15,
"user4" => 30,
"user19" => 36,
"user10" => 39,
];
$helper = [
"user4" => 3,
"user7" => 2,
"user10" => 4,
"user11" => 1,
"user19" => 5,
];
uksort ( $arr , function( $a , $b ) use ( $arr, $helper ) {
if ( $arr[$a] != $arr[$b] ) return $arr[$a] - $arr[$b];
return $helper[$a] - $helper[$b];
});
This will result to:
Array
(
[user11] => 15
[user7] => 15
[user4] => 30
[user19] => 36
[user10] => 39
)
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);
It feels I am going way over my head while discovering the ultimate usage of arrays.
I have two arrays, where the first has main keys, and the value is a count of files attached to that key.
The goal is to match the keys of this first array to the values in a second array, but still mainting (and show) the (value)count of Array-1 -- but for only the values in the second array.
Seems somewhat hazy perhaps, but here are the arrays. The second one has the values that should match the keys in the first.
(My problem is that I keep losing the values of array 1 with every attempt I make.)
Hope you can help me out with this one.
(working matches are keys like: 125, 2051 & 2214)
Array 1:
Array (
[6960] => 3
[2214] => 4
[2051] => 4
[6944] => 2
[6938] => 4
[1823] => 1
[766] => 6
[3993] => 4
[5896] => 6
[6927] => 2
[4220] => 3
[77] => 3
[83] => 1
[125] => 2
[6618] => 2
[196] => 1
[4072] => 12
[3718] => 1
[5918] => 1
[3388] => 10
[4500] => 13
[5968] => 2
[3000] => 2
[942] => 1
[4246] => 8
[5868] => 2
[6394] => 3
[1168] => 1
[2163] => 1
[1827] => 2
[2071] => 8
[4597] => 1
[1702] => 7
)
Array 2:
Array (
[0] => 1024
[1] => 1076
[2] => 111
[3] => 124
[4] => 125
[5] => 1301
[6] => 1409
[7] => 2051
[8] => 2214
[9] => 2636
[10] => 3246
[11] => 4838
[12] => 6946
[13] => 6955
[14] => 6961
[15] => 73
[16] => 74
[17] => 8
)
What about doing this:
<?php
$arr1 = array(1 => 1000, 500 => 1111, 1000 => 5000, 5000 => 5555);
$arr2 = array(1, 5000);
print_r(array_intersect_key($arr1, array_flip($arr2)));
OUTPUT:
(
[1] => 1000
[5000] => 5555
)
Or, using your data:
<?php
$arr1 = array(6960 => 3, 2214 => 4, 2051 => 4, 6944 => 2, 6938 => 4, 1823 => 1, 766 => 6, 3993 => 4, 5896 => 6, 6927 => 2, 4220 => 3, 77 => 3, 83 => 1, 125 => 2, 6618 => 2, 196 => 1, 4072 => 12, 3718 => 1, 5918 => 1, 3388 => 10, 4500 => 13, 5968 => 2, 3000 => 2, 942 => 1, 4246 => 8, 5868 => 2, 6394 => 3, 1168 => 1, 2163 => 1, 1827 => 2, 2071 => 8, 4597 => 1, 1702 => 7);
$arr2 = array(1024, 1076, 111, 124, 125, 1301, 1409, 2051, 2214, 2636, 3246, 4838, 6946, 6955, 6961, 73, 74, 8);
print_r(array_intersect_key($arr1, array_flip($arr2)));
OUTPUT:
Array
(
[2214] => 4
[2051] => 4
[125] => 2
)
array_interset_keys will find the intersection of arrays by keys, not values. Since your second array is an index based array (not an associative array) we need to first flip the keys and values using array_flip. Then the keys can be intersected.
Your question is somewhat unclear, but I think this is what you're looking for:
foreach( $array2 as $key)
{
$count = ( isset( $array1[ $key ]) ? $array1[ $key ] : 0);
echo $key . ' has ' . $count . ' files.';
}
Uhhmm.. i cant seem to understand what you want to imply.. but from the way i see it.. if you want to have the keys of array 1 as value to array 2.. just do this code..
foreach($array1 as $key=>$val) {
$array2[] = $key;
}
This should grab the KEYS of array1 and insert it to your array2[].
Hope this helps you.. Cheers :)
This should print out what you need:
foreach($array2 as $key=>$val) {
echo $val;
foreach($array1 as $key2 => $val2){
if($key == $val2){
echo $val2;
}
}
echo '\n'; // new line
}