字符串前的多重排序数字

时间:2018-02-13 03:56:44

标签: php algorithm

我想知道如何在字符串前对数字进行排序。我使用array_multisort对我的数组进行排序。

有我的样本数据

$arr = [
    [
        'company_name' => '',
        'expiryDate' => '2018.7',
        'classification' => 1
    ],
    [
        'company_name' => '',
        'expiryDate' => '2018.7',
        'classification' => '2-03'
    ],
    [
        'company_name' => '',
        'expiryDate' => '2018.7',
        'classification' => 3
    ],
    [
        'company_name' => '',
        'expiryDate' => '2018.7',
        'classification' => '2-01'
    ],
];

排序后的当前结果。字符串数字'2-01'在1到3之间排序

$arr = [
    [
        'company_name' => '',
        'expiryDate' => '2018.7',
        'classification' => 1
    ],
    [
        'company_name' => '',
        'expiryDate' => '2018.7',
        'classification' => '2-01'
    ],
    [
        'company_name' => '',
        'expiryDate' => '2018.7',
        'classification' => '2-03'
    ],
    [
        'company_name' => '',
        'expiryDate' => '2018.7',
        'classification' => 3
    ],
];

我的预期结果。我想在数字1和3之后排序字符串'2-01','2-03'

$arr = [
       [
          'company_name' => '',
          'expiryDate' => '2018.7',
          'classification' => 1
       ],
       [
          'company_name' => '',
          'expiryDate' => '2018.7',
          'classification' => 3
       ],
       [
          'company_name' => '',
          'expiryDate' => '2018.7',
          'classification' => '2-01'
       ],
       [
          'company_name' => '',
          'expiryDate' => '2018.7',
          'classification' => '2-03'
       ],
    ];

我的排序字段。我使用array_multisort对多个字段进行排序

$sortFields = [
    'classification' => SORT_ASC,
    'company_name' => SORT_ASC,
    'expiryDate' => SORT_ASC
];

2 个答案:

答案 0 :(得分:2)

尝试使用usort()和比较器:

// @param $arr array that you want to sort
// @param $sortby sort by $arr[$indexOfArray][$sortby]
// @param $isDate boolean
function sortItOutYourself(&$arr, $sortby, $isDate) {
    usort($arr, function($a1, $a2) use ($sortby, $isDate) {
        if($isDate)
            return DateTime::createFromFormat("Y.m", $a1[$sortby])->getTimestamp()
                - DateTime::createFromFormat("Y.m", $a2[$sortby])->getTimestamp();

        if( (gettype($a1[$sortby]) == "string" && gettype($a2[$sortby]) == "string") ||
            (gettype($a1[$sortby]) == "integer" && gettype($a2[$sortby]) == "integer") )
            return $a1[$sortby] > $a2[$sortby] ? 1 : -1;

        return gettype($a1[$sortby]) == "integer" && gettype($a2[$sortby]) == "string" ? -1 : 1;
    });
}

sortItOutYourself($arr, "classification", false);
sortItOutYourself($arr, "company_name", false);
sortItOutYourself($arr, "expiryDate", true);

答案 1 :(得分:0)

您可以使用usort()

usort($arr, function($a,$b) {
    // First, sort by classification. If it returns non-zero, use this
    // sort. If not, move to the next sort type.
    $sort = sortByClassification($a['classification'],$b['classification']);
    if ($sort !== 0) {
        return $sort;
    }

    // Second, sort by company name. If it returns non-zero, use this
    // sort. If not, move to the next sort type.
    $sort = sortByCompanyName($a['company_name'],$b['company_name']);
    if ($sort !== 0) {
        return $sort;
    }

    // Third, sort by expiry date. Since this is the last sort type,
    // we can just return it
    return sortByExpiryDate($a['expiryDate'],$b['expiryDate']);
});

function sortByClassification($a,$b) {
    // Both are numeric, so sort numerically
    if (is_numeric($a) && is_numeric($b)) {
        if ($a == $b) {
            return 0;
        }
        return ($a < $b) ? -1 : 1;
    }
    // Both are strings, so sort alphabetically
    if (!is_numeric($a) && !is_numeric($b)) {
        return strcmp($a, $b);
    }
    return is_numeric($a) ? -1 : 1;
}

function sortByCompanyName($a,$b) {
    return strcmp($a, $b);
}

function sortByExpiryDate($a, $b) {
    $a_explode = explode('.', $a);
    $a_expiry = new DateTime($a_explode[0].'-'.$a_explode[1].'-1');

    $b_explode = explode('.', $b);
    $b_expiry = new DateTime($b_explode[0].'-'.$b_explode[1].'-1');

    if ($a_expiry == $b_expiry) {
        return 0;
    }
    return $a_expiry < $b_expiry ? -1 : 1;
}

print_r($arr);

输出:

Array
(
    [0] => Array
        (
            [company_name] => 
            [expiryDate] => 2018.7
            [classification] => 1
        )

    [1] => Array
        (
            [company_name] => 
            [expiryDate] => 2018.7
            [classification] => 3
        )

    [2] => Array
        (
            [company_name] => 
            [expiryDate] => 2018.7
            [classification] => 2-01
        )

    [3] => Array
        (
            [company_name] => 
            [expiryDate] => 2018.7
            [classification] => 2-03
        )

)