Reputation: 2122
Original array:
$resolutions = array (
"Desktop monitor" => array (
//Standard 4:3
"800x600" => "800x600",
"1024x768" => "1024x768",
"1600x1200" => "1600x1200",
//Wide 16:10
"960x600" => "960x600",
"1280x800" => "1280x800",
"1440x900" => "1440x900",
"1680x1050" => "1680x1050",
"1920x1200" => "1920x1200",
),
"Apple" => array (
"DeviceX" => "2048x1536",
"DeviceY" => "1024x768",
),
);
Wanted array:
$resolutions = array (
"Desktop monitor" => array (
"800x600" => "800x600",//Standard 4:3
"960x600" => "960x600",//Wide 16:10
"1024x768" => "1024x768",//Standard 4:3
"1280x800" => "1280x800",//Wide 16:10
"1440x900" => "1440x900",//Wide 16:10
"1600x1200" => "1600x1200",//Standard 4:3
"1680x1050" => "1680x1050",//Wide 16:10
"1920x1200" => "1920x1200",//Wide 16:10
),
"Apple" => array (
"DeviceY" => "1024x768",
"DeviceX" => "2048x1536",
),
);
What I have tried:
foreach ($resolutions as $screen => $resolution) {
foreach($resolution as $key => $val) {
$newarray[$key] = $row[$val];
}
array_multisort($newarray, SORT_DESC, $resolution);
}
I thought that I'm half way to end, but the code above gave me some non sense (for me), ie: first goes resolution 1024x768, then 1280x800, followed by 1440x900 and in the end is 800x600.
Upvotes: 2
Views: 165
Reputation: 48031
Because your sample dimension values always show the larger number before the x
delimiter and there are no significantly lean or fat ratios, a key-preserving natural sort on each set will do the trick. Demo
array_walk(
$resolutions,
function (&$row) {
asort($row, SORT_NATURAL);
}
);
var_export($resolutions);
If your project has more squirrelly dimension values, then iterated calculations should be minimized. Demo
array_walk(
$resolutions,
function (&$row) {
array_multisort(
array_map(
fn($v) => array_product(sscanf($v, '%dx%d')),
$row
),
$row
);
}
);
var_export($resolutions);
Upvotes: 0
Reputation: 24425
This is a quick hack looking specifically for the Desktop monitor
array key. ksort
will sort by array key, but it doesn't sort well when you have an x
in the middle of some numbers. Here's my solution:
ksort
to sort new arrayarray_walk
new array to create output array which looks like originalYou could do the same thing for other arrays inside your original array e.g. Apple
by using the value instead of the key as the resolution, and put the array_walk
etc inside a loop.
Upvotes: 0
Reputation: 27914
The problem is that you are sorting alphabetically. You will need to calculate the size of each resolution to sort them correctly. This will require writing a custom comparison function that calculate the resolution sizes and compare them.
foreach ($resolutions as &$resolution)
uasort($resolution, function ($a, $b) { return array_product(explode('x', $a)) - array_product(explode('x', $b)); });
Upvotes: 1
Reputation:
Just looking at what you've put there, two things stand out:
try:
foreach ($resolutions as $resolution) {
asort($resolution);
}
Upvotes: 0