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

发布于 2024-12-13 12:36:15 字数 1904 浏览 0 评论 0原文

因此,我不确定标题是否最适合它,但数组如下所示:

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(),但我不确定如何有效地迭代循环以便按照我给出的条件进行排序。

So I'm not exactly sure if the title fits it best, but here's what the array looks like:

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'
          )
)

How I'd like this data to be sorted would be the following:

  1. Preserve the order of the categories
  2. Within the categories, order by date DESC
  3. If dates appear multiple times, order by data alphabetically ASC

The example array would then be sorted to array ([0], [1], [4], [2], [3]), more specifically:

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'
          )
)

My issue is I know I'll need usort and/or array_multisort(), but I'm not sure exactly sure how to efficiently iterate through a loop in order to sort with the criteria I gave.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浊酒尽余欢 2024-12-20 12:36:15

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

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

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

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

另一个改进是日期的存储方式。美国日期格式完全无法用于排序,无论是作为字符串还是数值。将其转换为 unix 时间戳,或使用 ISO 日期格式“YYYY-MM-DD”。两者都可以轻松进行比较,无需多费周折。

Your problem can easily be solved with a nice comparison function and uasort() or usort(). Here is how it works:

Your comparison function accepts two parameters, which are elements of the array you sort. Return -1 if the first parameter should appear first in the sorted array, return 1 if the second parameter should appear first, and return 0 if both are considered equal in the sorting order.

Your order criteria is like: Sort by category. If category is the same, sort by date. If date is the same, sort by data.

Unfortunately your array is not properly structured. What if another category=Value_3 appears as the last element in the array. Should it be grouped with the other Value_3 entries, or should it be sorted alone? Depending on this answer, the array should be restructured for easier sorting.

Another improvement is the way the date is stored. America date format is completely unusable for sorting, neither as a string nor as a numeric value. Either transform it to a unix timestamp, or use ISO date format "YYYY-MM-DD". Both can easily be compared without further ado.

流心雨 2024-12-20 12:36:15

假设您的数组位于 $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"
    }
}

Supposing your array in $data variable, try this:

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

// outputs

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"
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文