在子数组中按多个值对PHP数组进行排序

问题描述 投票:2回答:2

所以我不确定标题是否最合适,但这是数组的样子:

array (
   [0] => array (
              [category] => 'Value_1'
              [date]     => '01/01/2011'
              [data]     => 'A'
          )
   [1] => array (
              [category] => 'Value_3'
              [date]     => '01/01/2000'
              [data]     => 'B'
          )
   [2] => array (
              [category] => 'Value_2'
              [date]     => '01/01/2011'
              [data]     => 'D'
          )
   [3] => array (
              [category] => 'Value_2'
              [date]     => '01/01/2010'
              [data]     => 'A'
          )
   [4] => array (
              [category] => 'Value_2'
              [date]     => '01/01/2011'
              [data]     => 'C'
          )
)

我希望如何对这些数据进行排序如下:

  1. 保留类别的顺序
  2. 在类别中,按日期DESC排序
  3. 如果日期多次出现,请按字母顺序按ASC排序

然后将示例数组排序为array ([0], [1], [4], [2], [3]),更具体地说:

array (
   [0] => array (
              [category] => 'Value_1'
              [date]     => '01/01/2011'
              [data]     => 'A'
          )
   [1] => array (
              [category] => 'Value_3'
              [date]     => '01/01/2000'
              [data]     => 'B'
          )
   [2] => array (
              [category] => 'Value_2'
              [date]     => '01/01/2011'
              [data]     => 'C'
          )
   [3] => array (
              [category] => 'Value_2'
              [date]     => '01/01/2011'
              [data]     => 'D'
          )
   [4] => array (
              [category] => 'Value_2'
              [date]     => '01/01/2010'
              [data]     => 'A'
          )
)

我的问题是我知道我需要usort和/或array_multisort(),但我不确定如何有效地迭代循环以便按照我给出的标准进行排序。

php arrays sorting usort
2个回答
1
投票

假设你的数组在$data变量中,试试这个:

$data = Array(
    0 => array(
        "category" => 'Value_1',
        "date" => '01/01/2011',
        "data" => 'A'
    ),
    1 => array(
        "category" => 'Value_3',
        "date" => '01/01/2000',
        "data" => 'B'
    ),
    2 => array(
        "category" => 'Value_2',
        "date" => '01/01/2011',
        "data" => 'D'
    ),
    3 => array(
        "category" => 'Value_2',
        "date" => '01/01/2010',
        "data" => 'A'
    ),
    4 => array(
        "category" => 'Value_2',
        "date" => '01/01/2011',
        "data" => 'C'
    )
);

$sorted = false;
foreach ($data as $index => $row) {
    $data[$index]['date'] = strtotime($data[$index]['date']);
}
while (!$sorted) {
    $aux = null;
    $prevCat = null;
    $prevDate = null;
    $prevData = null;
    foreach ($data as $index => $row) {
        if ($prevCat != $row['category']) {
            $prevCat = $row['category'];
            $prevDate = $row['date'];
            $prevData = $row['data'];
            continue;
        } else {
            if ($row['date'] > $prevDate) {
                $sorted = false;
                $aux = $data[$index - 1];
                $data[$index - 1] = $row;
                $data[$index] = $aux;
                break;
            }
            if ($row['date'] == $prevDate && $row['data'] < $prevData) {
                $sorted = false;
                $aux = $data[$index - 1];
                $data[$index - 1] = $row;
                $data[$index] = $aux;
                break;
            }
            $prevCat = $row['category'];
            $prevDate = $row['date'];
            $prevData = $row['data'];
        }
    }
    $sorted = ($aux == null);
}
foreach ($data as $index => $row)
    $data[$index]['date'] = date("m/d/Y", $data[$index]['date']);
var_dump($data);

//输出

array(5) {
    [0] => array(3) {
        ["category"] => string(7) "Value_1"
        ["date"] => string(10) "01/01/2011                                                               
        ["data"] => string(1) "A"
    }
    [1] => array(3) {
        ["category"] => string(7) "Value_3"
        ["date"] => string(10) "01/01/2000"
        ["data"] => string(1) "B"
    }
    [2] => array(3) {
        ["category"] => string(7) "Value_2"
        ["date"] => string(10) "01/01/2011"
        ["data"] => string(1) "C"
    }
    [3] => array(3) {
        ["category"] => string(7) "Value_2"
        ["date"] => string(10) "01/01/2011"
        ["data"] => string(1) "D"
    }
    [4] => array(3) {
        ["category"] => string(7) "Value_2"
        ["date"] => string(10) "01/01/2010"
        ["data"] => string(1) "A"
    }
}

3
投票

使用一个很好的比较函数和uasort()usort()可以轻松解决您的问题。下面是它的工作原理:

您的比较函数接受两个参数,这些参数是您排序的数组的元素。如果第一个参数应首先出现在排序数组中,则返回-1;如果第一个参数应首先出现,则返回1;如果在排序顺序中认为两个参数都相等,则返回0。

您的订单标准如下:按类别排序。如果类别相同,则按日期排序。如果日期相同,则按数据排序。

不幸的是,您的阵列结构不正确。如果另一个category = Value_3作为数组中的最后一个元素出现,该怎么办?它应该与其他Value_3条目分组,还是应该单独排序?根据此答案,应重新构建阵列以便于排序。

另一项改进是存储日期的方式。美国日期格式完全不能用于排序,既不是字符串也不是数字值。将其转换为unix时间戳,或使用ISO日期格式“YYYY-MM-DD”。两者都可以轻松比较而不用多说。

© www.soinside.com 2019 - 2024. All rights reserved.