简体   繁体   English

如何使用 2 个特定键的值对多维数组进行排序

[英]How to sort multidimensional array using value of 2 specific keys

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?如何使用BrandDisplayOrder键的值对多维数组进行排序? 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 . Same Brand将一起显示,然后相同品牌的记录将按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.如果按 2 个键的值排序过于复杂,则仅按DisplayOrder键进行升序排序也可以。 So resulting array data will be displayed in order of 1, 4, 6, 9 .因此生成的数组数据将按1, 4, 6, 9的顺序显示。 That means Brand key will not be considered in this case.这意味着在这种情况下将不考虑Brand密钥。

Thank You,谢谢你,

EDIT编辑

I tried following 2 codes taken from inte.net but both are giving illegal offset error.我尝试遵循从 inte.net 获取的 2 个代码,但都给出了illegal offset错误。 I tried below code to sort array only on DisplayOrder key.我尝试使用以下代码仅在DisplayOrder键上对数组进行排序。

#1 #1

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

#2 #2

usort($result, function($a, $b) {
    return $a['DisplayOrder'] <=> $b['DisplayOrder'];
});

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.首先,您只想对结果中的产品数组进行排序,因此将其传递给您的usort函数而不是整个结果数组。

Second, you need to make your usorts smarter.其次,您需要使您的usorts更智能。 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.第一个是简单的usort function,它根据品牌名称的字母顺序和结果中的显示顺序进行比较。 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.第二个使用基本的 class 来定义自定义排序顺序,以及使用该列表的比较 function,如果品牌相同或不在列表中,则进入基本比较。 This shows how you can use classes in usort , which some people seem to struggle with.这显示了如何在usort中使用类,有些人似乎对此感到困惑。

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

You want to sort $arr['products'].您想要对 $arr['products'] 进行排序。 That must also be passed to usort.这也必须传递给 usort。 The function sorts by DisplayOrder, Brand. function 按 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
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM