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:
我希望如何对这些数据进行排序如下:
- Preserve the order of the categories
- 保留类别的顺序
- Within the categories, order by date DESC
- 在类别中,按日期DESC排序
- If dates appear multiple times, order by data alphabetically ASC
- 如果日期多次出现,请按字母顺序按ASC排序
The example array would then be sorted to array ([0], [1], [4], [2], [3])
, more specifically:
然后将示例数组排序为数组([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'
)
)
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.
我的问题是我知道我需要usort和/或array_multisort(),但我不确定如何有效地迭代循环以便按照我给出的标准进行排序。
2 个解决方案
#1
1
Supposing your array in $data
variable, try this:
假设你的数组在$ data变量中,试试这个:
<?php
$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"
}
}
#2
2
Your problem can easily be solved with a nice comparison function and uasort()
or usort()
. Here is how it works:
使用一个很好的比较函数和uasort()或usort()可以很容易地解决你的问题。下面是它的工作原理:
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.
您的比较函数接受两个参数,这些参数是您排序的数组的元素。如果第一个参数应该首先出现在排序数组中,则返回-1;如果第一个参数应该首先出现,则返回1;如果在排序顺序中认为两个参数都相等,则返回0。
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.
不幸的是,您的阵列结构不正确。如果另一个category = Value_3作为数组中的最后一个元素出现,该怎么办?它应该与其他Value_3条目分组,还是应该单独排序?根据此答案,应重新构建阵列以便于排序。
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.
另一个改进是存储日期的方式。美国日期格式完全不能用于排序,既不能作为字符串也不能作为数值。将其转换为unix时间戳,或使用ISO日期格式“YYYY-MM-DD”。两者都可以轻松比较而不用多说。
#1
1
Supposing your array in $data
variable, try this:
假设你的数组在$ data变量中,试试这个:
<?php
$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"
}
}
#2
2
Your problem can easily be solved with a nice comparison function and uasort()
or usort()
. Here is how it works:
使用一个很好的比较函数和uasort()或usort()可以很容易地解决你的问题。下面是它的工作原理:
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.
您的比较函数接受两个参数,这些参数是您排序的数组的元素。如果第一个参数应该首先出现在排序数组中,则返回-1;如果第一个参数应该首先出现,则返回1;如果在排序顺序中认为两个参数都相等,则返回0。
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.
不幸的是,您的阵列结构不正确。如果另一个category = Value_3作为数组中的最后一个元素出现,该怎么办?它应该与其他Value_3条目分组,还是应该单独排序?根据此答案,应重新构建阵列以便于排序。
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.
另一个改进是存储日期的方式。美国日期格式完全不能用于排序,既不能作为字符串也不能作为数值。将其转换为unix时间戳,或使用ISO日期格式“YYYY-MM-DD”。两者都可以轻松比较而不用多说。