如何按多个键,字符串和整数的值对多维数组进行排序

时间:2017-09-12 16:33:52

标签: php arrays sorting multidimensional-array

我有一系列人(立法者)列出他们的级别,州,分庭和地区。我喜欢的是根据这4个键的值对数组进行排序,但是使用自定义顺序,因为其中一些值是字符串。例如,我想首先按" level"排序。顺序为("联邦","州",然后是其他任何东西),然后按字母顺序递增,然后通过("州长",&# 34; upper"," lower&#34 ;,然后是其他任何东西),然后按数字顺序递增。这是我使用的数组的简短示例。

Array
(
[0] => stdClass Object
    (
        [district] => 15
        [state] => fl
        [level] => state
        [chamber] => upper

    )

[1] => stdClass Object
    (
        [district] => 50
        [state] => fl
        [level] => state
        [chamber] => lower
    )
[2] => stdClass Object
    (
        [district] => 0
        [state] => fl
        [level] => state
        [chamber] => governor

    )
)

2 个答案:

答案 0 :(得分:2)

@ BusyBeaver的解决方案cmp() / compare()功能非常复杂且难以更新,如果您想要更改订单,或者上帝禁止添加另一个字段!

这就是我想出来的:

<?php
function sortValue($key, $value)
{
    static $arrValueOrder = [
        'level' => ['federal', 'state'],
        'chamber' => ['governor', 'upper', 'lower']
    ];

    if (array_key_exists($key, $arrValueOrder)) {
        if (($result = array_search($value, $arrValueOrder[$key])) === false) {
            $result = count($arrValueOrder[$key]);
        }
    } else {
        $result = $value;
    }
    return $result;
}

function cmp($a, $b)
{
    static $arrFieldOrder = ['level', 'state', 'chamber', 'district'];

    $result = 0;
    reset($arrFieldOrder);
    while ($result === 0 && list($key, $value) = each($arrFieldOrder)) {
        $aSortValue = sortValue($value, $a->$value);
        $bSortValue = sortValue($value, $b->$value);
        if ($aSortValue > $bSortValue) {
            $result = 1;
        } elseif ($aSortValue < $bSortValue) {
            $result = -1;
        }
    }
    return $result;
}

// setup some test data
$arrData = [
    (object)['district' => 15, 'state' => 'fl', 'level' => 'state', 'chamber' => 'upper'],
    (object)['district' => 15, 'state' => 'tx', 'level' => 'federal', 'chamber' => 'lower'],
    (object)['district' => 50, 'state' => 'fl', 'level' => 'state', 'chamber' => 'lower'],
    (object)['district' => 15, 'state' => 'tx', 'level' => 'federal', 'chamber' => 'upper'],
    (object)['district' => 0, 'state' => 'fl', 'level' => 'state', 'chamber' => 'governor'],
    (object)['district' => 15, 'state' => 'tx', 'level' => 'federal', 'chamber' => 'governor'],
    (object)['district' => 15, 'state' => 'tx', 'level' => 'federal', 'chamber' => 'foo'],
    (object)['district' => 15, 'state' => 'fl', 'level' => 'federal', 'chamber' => 'upper']
];

// sort it
usort($arrData, 'cmp');

// dump the result
var_dump($arrData);

答案 1 :(得分:1)

usort()可以解决您的问题,您只需编写一个可以按需运行的良好比较功能。

select
    Meeting1,
    Meeting2,
    Meeting3,
    Meeting4,
    Meeting5,
    (
        select count(*)
        from (values (Meeting1), (Meeting2), (Meeting3), (Meeting4), (Meeting5)) as v(col)
        where v.col is not null
    ) as meeting_count
from Table

您还可以考虑面向对象的解决方案(仍需要比较功能......)

<div ng-repeat="item in NewArrivals">
  <div ng-if="userDiscount">{{item.NewPrice * userDiscount | number:2}}</div>
  <div ng-if="userCredit">{{item.NewPrice - userCredit | number:2}}</div>
<div>