php - Sort an associative/multidimensional array based on a sub-object array value
one text
Solution:
According to your logic, we need to sort the array by badge condition and within the campaign badge group we need to sort by a product name. Please take a look at the following snippet.
<?php
declare(strict_types=1);
$campaignBadge = new \stdClass();
$campaignBadge->badge_id = 3;
$campaignBadge->badge_name = 'campaign';
$campaignBadge->badge_published = 1;
$campaignBadge->badge_access = 'all';
$whateverBadge = new \stdClass();
$whateverBadge->badge_id = 5;
$whateverBadge->badge_name = 'whatever';
$whateverBadge->badge_published = 1;
$whateverBadge->badge_access = 'all';
$product1 = new \stdClass();
$product1->product_id = 195;
$product1->product_name = 'Product name 1';
$product1->badges = [
$campaignBadge,
];
$product2 = new \stdClass();
$product2->product_id = 290;
$product2->product_name = 'Amazing product';
$product2->badges = [
$whateverBadge,
];
$product3 = new \stdClass();
$product3->product_id = 102;
$product3->product_name = 'Some product';
$product3->badges = [
$whateverBadge,
];
$product4 = new \stdClass();
$product4->product_id = 250;
$product4->product_name = 'Awesome product';
$product4->badges = [
$campaignBadge,
];
$products = [
$product1,
$product2,
$product3,
$product4,
];
usort($products, static function ($a, $b) {
$aHasCampaignBadge = false;
foreach ($a->badges as $badge) {
if ('campaign' === $badge->badge_name) {
$aHasCampaignBadge = true;
break;
}
}
$bHasCampaignBadge = false;
foreach ($b->badges as $badge) {
if ('campaign' === $badge->badge_name) {
$bHasCampaignBadge = true;
break;
}
}
if (!$aHasCampaignBadge && !$bHasCampaignBadge) {
return 0;
}
if ($aHasCampaignBadge && $bHasCampaignBadge) {
return strcmp($a->product_name, $b->product_name);
}
return $aHasCampaignBadge < $bHasCampaignBadge;
});
var_dump($products);
Source