2

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.

0

4 Answers 4

1

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)); });
Sign up to request clarification or add additional context in comments.

Comments

0

Just looking at what you've put there, two things stand out:

  • You're looping through the outer array and sorting a single-dimensional array using multisort; I would recommend just using asort().
  • Not quite sure what's going on there with $resolutions being passed in as the thrid paramter. It wants an array of sort flags.

try:

foreach ($resolutions as $resolution) { 
        asort($resolution);
    }

1 Comment

This will not impact the original array because $resolution is not modifiable by reference.
0

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:

  • Loop through array
  • Build new array with only first half of resolution as array key
  • Use ksort to sort new array
  • array_walk new array to create output array which looks like original

You 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.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.