Home > Back-end >  Sorting an array by text of first subarray in each row
Sorting an array by text of first subarray in each row

Time:11-17

I have an array stored as $product_categories. A sample of this array is:

$array = [
    [
        ['id' => 10, 'text' => 'Latex'],
        ['id' => 15, 'text' => 'Occasion Latex'],
        ['id' => 82, 'text' => 'Christmas'],
    ],
    [
        ['id' => 11, 'text' => 'Accessories'],
        ['id' => 97, 'text' => 'Retail Accessories'],
        ['id' => 558, 'text' => 'Super Stuffer'],
    ],
    [
        ['id' => 374, 'text' => 'Party Supplies'],
        ['id' => 1488, 'text' => 'Party by Occasion'],
        ['id' => 1493, 'text' => 'Christmas'],
    ],
];

I want to sort it ONLY by the key 'text' in [0], which would give me a result of

[
    [
        ['id' => 11, 'text' => 'Accessories'],
        ['id' => 97, 'text' => 'Retail Accessories'],
        ['id' => 558, 'text' => 'Super Stuffer'],
    ],
    [
        ['id' => 10, 'text' => 'Latex'],
        ['id' => 15, 'text' => 'Occasion Latex'],
        ['id' => 82, 'text' => 'Christmas'],
    ],
    [
        ['id' => 374, 'text' => 'Party Supplies'],
        ['id' => 1488, 'text' => 'Party by Occasion'],
        ['id' => 1493, 'text' => 'Christmas'],
    ],
];

I've tried using

$product_categories = usort($product_categories, 'sortAlphabetically');

function sortAlphabetically($a, $b) {
    return strcmp($a['text'], $b['text']);
}

Using that, a print_r() of the array simply returns 1.

I thought usort() was the correct way to sort the array but clearly I'm doing something wrong here.

CodePudding user response:

Your array:

$array = [
    '0' => [
        '0' => [
            'id'   => 10,
            'text' => 'Latex',
        ],
        '1' => [
            'id'   => 15,
            'text' => 'Occasion Latex',
        ],
        '2' => [
            'id'   => 82,
            'text' => 'Christmas',
        ],
    ],
    '1' => [
        '0' => [
            'id'   => 11,
            'text' => 'Accessories',
        ],
        '1' => [
            'id'   => 97,
            'text' => 'Retail Accessories',
        ],
        '2' => [
            'id'   => 558,
            'text' => 'Super Stuffer',
        ],
    ],
    '2' => [
        '0' => [
            'id'   => 374,
            'text' => 'Party Supplies',
        ],
        '1' => [
            'id'   => 1488,
            'text' => 'Party by Occasion',
        ],
        '2' => [
            'id'   => 1493,
            'text' => 'Christmas',
        ],
    ],
];

The sort:

// uasort(): "Sort an array with a user-defined comparison function
//            and maintain index association"
uasort($array, function (array $a, array $b) {
    // "I want to sort it ONLY by the key 'text' in [0]"
    // Get first from array (aka [0]).
    // (You could change that to fix $a[0] and $b[0] if you want|need to.)
    $aFirst = reset($a); 
    $bFirst = reset($b); 
    $offset = 'text';
    if ($aFirst[$offset] == $bFirst[$offset]) {
        return 0;
    }
    // a < b === asc ; a > b === desc
    return ($aFirst[$offset] < $bFirst[$offset]) ? -1 : 1;
});
echo var_export($array, true) . PHP_EOL;

Results in:

[
    1 => [
        0 => [
            'id'   => 11,
            'text' => 'Accessories',
        ],
        1 => [
            'id'   => 97,
            'text' => 'Retail Accessories',
        ],
        2 => [
            'id'   => 558,
            'text' => 'Super Stuffer',
        ],
    ],
    0 => [
        0 => [
            'id'   => 10,
            'text' => 'Latex',
        ],
        1 => [
            'id'   => 15,
            'text' => 'Occasion Latex',
        ],
        2 => [
            'id'   => 82,
            'text' => 'Christmas',
        ],
    ],
    2 => [
        0 => [
            'id'   => 374,
            'text' => 'Party Supplies',
        ],
        1 => [
            'id'   => 1488,
            'text' => 'Party by Occasion',
        ],
        2 => [
            'id'   => 1493,
            'text' => 'Christmas',
        ],
    ],
]

CodePudding user response:

You only need to access the subarray data using array syntax as you've expressed in English. (Demo)

usort(
    $array,
    function($a, $b) {
        return $a[0]['text'] <=> $b[0]['text'];
    }
);
var_export($array);

Or in PHP7.4 or higher:

usort($array, fn($a, $b) => $a[0]['text'] <=> $b[0]['text']);
  • Related