0
Array ( 
    [products] => Array ( 
        [0] => Array ( 
            [LOTid] => Array ( [0] => 20200901000001 ) 
            [Brand] => SAMSUNG 
            [Product] => TV 
            [DisplayOrder] => 6 ) 
        [1] => Array ( 
            [LOTid] => Array ( [0] => 20200901000002 ) 
            [Brand] => LG 
            [Product] => TV 
            [DisplayOrder] => 9 )
        [2] => Array ( 
            [LOTid] => Array ( [0] => 20200901000003 ) 
            [Brand] => SAMSUNG 
            [Product] => MOBILE 
            [DisplayOrder] => 1 )  
        [3] => Array ( 
            [LOTid] => Array ( [0] => 20200901000002 ) 
            [Brand] => LG 
            [Product] => MOBILE
            [DisplayOrder] => 4 )
    ) 
    [status] => ok 
)  

How to sort above multidimensional array using values of Brand and DisplayOrder keys? So sorted array will be arranged like following sample. Same Brand will display together and then records of same brand will be displayed in ascending order of DisplayOrder.

Array ( 
    [products] => Array ( 
        [0] => Array ( 
            [LOTid] => Array ( [0] => 20200901000003 ) 
            [Brand] => SAMSUNG 
            [Product] => MOBILE 
            [DisplayOrder] => 1 )
        [1] => Array ( 
            [LOTid] => Array ( [0] => 20200901000001 ) 
            [Brand] => SAMSUNG 
            [Product] => TV 
            [DisplayOrder] => 6 ) 
        [2] => Array ( 
            [LOTid] => Array ( [0] => 20200901000002 ) 
            [Brand] => LG 
            [Product] => MOBILE
            [DisplayOrder] => 4 )
        [3] => Array ( 
            [LOTid] => Array ( [0] => 20200901000002 ) 
            [Brand] => LG 
            [Product] => TV 
            [DisplayOrder] => 9 )
    ) 
) 

If sorting by values of 2 keys is too complex then ascending sorting on just DisplayOrder key will also work. So resulting array data will be displayed in order of 1, 4, 6, 9. That means Brand key will not be considered in this case.

Thank You,

EDIT

I tried following 2 codes taken from internet but both are giving illegal offset error. I tried below code to sort array only on DisplayOrder key.

#1

function method1($a,$b) 
    {
        return ($a["products"]["DisplayOrder"] <= $b["products"]["DisplayOrder"]) ? -1 : 1;
    }
usort($result, "method1");

#2

usort($result, function($a, $b) {
    return $a['DisplayOrder'] <=> $b['DisplayOrder'];
});
2
  • Please don't just ask us to solve the problem for you. Show us how you tried to solve the problem yourself, then show us exactly what the result was, and tell us why you feel it didn't work. Give us a clear explanation of what isn't working and provide a Minimal, Complete, and Verifiable example. Read How to Ask a good question. Be sure to take the tour and read this. Commented Sep 1, 2020 at 12:47
  • hello, I just added some code that I tried with error I am getting. Commented Sep 1, 2020 at 12:56

2 Answers 2

1

You have a few of issues here. First, you only want to sort the products array within the results, so pass that into your usort functions instead of the entire results array.

Second, you need to make your usorts smarter. They are just functions that return an indication of how the elements compare, you can put whatever logic you want inside them.

The third thing I see is that you do not seem to want the results sorted by brand name alphabetically, you want Samsung first. I'm guessing you will want to define a custom sort order for brands that put the most popular brands first. Or maybe you work for a brand that always wants to be listed first, or have promotional agreements - whatever.

Here are two ways you can solve the problem. The first is a simple usort function that compares based upon the brand name alphabetically, and the display order in the results. The second uses a basic class to define a custom sort order, and a compare function that uses that list, and falls through to the basic comparisons if the brands are the same, or not present in the list. This shows how you can use classes in usort, which some people seem to struggle with.

<?php
$result = [
    'products' => [
        [
            'LOTid'        => [20200901000001],
            'Brand'        => 'SAMSUNG',
            'Product'      => 'TV',
            'DisplayOrder' => 6
        ],
        [
            'LOTid'        => [20200901000002],
            'Brand'        => 'LG',
            'Product'      => 'TV',
            'DisplayOrder' => 9],
        [
            'LOTid'        => [20200901000003],
            'Brand'        => 'SAMSUNG',
            'Product'      => 'MOBILE',
            'DisplayOrder' => 1],
        [
            'LOTid'        => [20200901000002],
            'Brand'        => 'LG',
            'Product'      => 'MOBILE',
            'DisplayOrder' => 4]
    ],
    'status'   => 'ok'
];

// Simple sort based upon contents of the results
function sortByBrandAndDisplayOrder($a, $b)
{
    // Sort on brand name
    if($a['Brand'] < $b['Brand'])
    {
        return -1;
    }
    if($a['Brand'] > $b['Brand'])
    {
        return 1;
    }

    // Sort on display order if brands are equal
    return $a['DisplayOrder'] <=> $b['DisplayOrder'];
}

//Pass in the products section of the results - you don't want to sort the outer results array
usort($result['products'], 'sortByBrandAndDisplayOrder');
print_r($result);

// Make a class that can hold a custom order definition
class ProductSort
{
    private static $_brandOrder = [
        'SAMSUNG'=>0,
        'LG'=>1
    ];

    static function sortByBrandAndDisplayOrder($a, $b)
    {
        //If both brands are present, sort on the custom brand order
        if(array_key_exists($a['Brand'], self::$_brandOrder) && array_key_exists($b['Brand'], self::$_brandOrder))
        {
            // If both brands have the same display order (same brand), will fall through to
            if(self::$_brandOrder[$a['Brand']] < self::$_brandOrder[$b['Brand']])
            {
                return -1;
            }
            if(self::$_brandOrder[$a['Brand']] > self::$_brandOrder[$b['Brand']])
            {
                return 1;
            }
        }
        elseif(array_key_exists($a['Brand'], self::$_brandOrder))
        {
            return -1;
        }
        elseif(array_key_exists($b['Brand'], self::$_brandOrder))
        {
            return 1;
        }

        // Sort on brand name
        if($a['Brand'] < $b['Brand'])
        {
            return -1;
        }
        if($a['Brand'] > $b['Brand'])
        {
            return 1;
        }

        //Sort on DisplayOrder in the results
        return $a['DisplayOrder'] <=> $b['DisplayOrder'];
    }
}

usort($result['products'], ['ProductSort', 'sortByBrandAndDisplayOrder']);
print_r($result);
Sign up to request clarification or add additional context in comments.

Comments

1

You want to sort $arr['products']. That must also be passed to usort. The function sorts by DisplayOrder, Brand.

$arr = ['products' => [
         ['LOTid' => [20200901000001],'Brand' => 'SAMSUNG', 'Product' => 'TV', 'DisplayOrder' => 6],
         ['LOTid' => [20200901000002],'Brand' => 'LG', 'Product' => 'TV', 'DisplayOrder' => 9],
         ['LOTid' => [20200901000003],'Brand' => 'SAMSUNG', 'Product' => 'MOBILE', 'DisplayOrder' => 1],
         ['LOTid' => [20200901000002],'Brand' => 'LG', 'Product' => 'MOBILE', 'DisplayOrder' => 4],
 
    ], 
    'status' => 'ok'
]; 

usort($arr['products'],function($a,$b){
  $cmp1 = $a['DisplayOrder'] <=> $b['DisplayOrder'];  //rank 1
  return $cmp1 ? $cmp1 : $a['Brand'] <=> $b['Brand'];  //rank 2
});

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.