0

I need to sort the rows of my multidimensional array by the first element of its subarray. Each row may have a dynamically named first element in its attribute subarray. I want to sort first by the first element's key, then by the value of the first element.

My input array looks like this:

$array = [
    [
        'tag' => 'meta',
        'type' => 'complete',
        'attributes' => ['property' => 'og:type', 'content' => 'website']
    ],
    [
        'tag' => 'meta',
        'type' => 'complete',
        'attributes' => ['name' => 'robots', 'content' => 'noindex, nofollow']
    ],
    [
        'tag' => 'meta',
        'type' => 'complete',
        'attributes' => ['name' => 'application', 'content' => 'My Application']
    ],
    [
        'tag' => 'meta',
        'type' => 'complete',
        'attributes' => ['http-equiv' => 'content-type', 'content' => 'text/html; charset=utf-8']
    ]
];

How I can sort it with array_multisort()?

Desired output:

Array
(
    [0] => Array
        (
            [tag] => meta
            [type] => complete
            [attributes] => Array
                (
                    [http-equiv] => content-type
                    [content] => text/html; charset=utf-8
                )
        )
    [1] => Array
        (
            [tag] => meta
            [type] => complete
            [attributes] => Array
                (
                    [name] => application
                    [content] => My Application
                )
        )
    [2] => Array
        (
            [tag] => meta
            [type] => complete
            [attributes] => Array
                (
                    [name] => robots
                    [content] => noindex, nofollow
                )
        )
    [3] => Array
        (
            [tag] => meta
            [type] => complete
            [attributes] => Array
                (
                    [property] => og:type
                    [content] => website
                )
        )
)

I am having some difficulty because the first column of attributes is unpredictably keyed.

4
  • How do you want to sort it? Alphabetically? Or in a specified custom order? I am asking about both the first array key and the value of it. Please provide more details about your desired algorithm. It would be easier to convert it into code. Commented Nov 30, 2020 at 11:03
  • So your actual problem is, that you don’t know how to access the first item of an associative array, when the keys are unknown? Commented Nov 30, 2020 at 11:03
  • 1
    Does this answer your question? Get array value with unknown key name Commented Nov 30, 2020 at 11:03
  • For first column (key assume value: http-equiv, name and property) and if first column same name then for value of it as in output example. Commented Nov 30, 2020 at 11:59

2 Answers 2

1

usort with custom callback will look like:

usort($arr, function($a, $b) {
   $aKeyFirst = array_key_first($a['attributes']);
   // fallback, php version < 7.3
   //$aKeyFirst = array_keys($a['attributes'])[0];
   
   $bKeyFirst = array_key_first($b['attributes']);
   // fallback, php version < 7.3
   //$bKeyFirst = array_keys($b['attributes'])[0];
   
   if ($aKeyFirst !== $bKeyFirst) {
       return strcmp($aKeyFirst, $bKeyFirst);
   } else {
       return strcmp($a['attributes'][$aKeyFirst], $b['attributes'][$bKeyFirst]);
   }
});
Sign up to request clarification or add additional context in comments.

Comments

0

It will be most direct/performant to build two flat arrays from the attribute keys and values then use array_multisort() -- this involves no iterated function calls.

  • The [..] syntax in the first foreach() is a technique called "array destructuring" and allows you to isolate only the data that you need within the body of the loop.
  • The [] syntax in the nested foreach() signature pushes keys and values into the output arrays.
  • The break condition ensures that we never push more than the first element from each attribute subarray into the result array.

Code: (Demo)

foreach ($array as ['attributes' => $attr]) {
    foreach ($attr as $keys[] => $values[]) {
        break;
    }
}
array_multisort($keys, $values, $array);
var_export($array);

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.