所以我不确定标题是否最合适,但这是数组的样子:
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'
)
)
我希望如何对这些数据进行排序如下:
保留类别的顺序
在类别中,按日期排序DESC
如果日期多次出现,则按数据字母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(),但是我不确定要如何有效地循环遍历才能与我给出的条件进行排序。
您能告诉我们上面数组的期望输出吗?
我继续并添加了一些清晰度。
您可以通过一个很好的比较函数和uasort()或usort()轻松解决您的问题。下面是它的工作原理:
比较函数接受两个参数,它们是要排序的数组的元素。如果第一个参数应首先出现在排序数组中,则返回-1;如果第二个参数应首先出现,则返回1;如果两个参数在排序顺序中都相等,则返回0。
您的订单条件如下:按类别排序。如果类别相同,则按日期排序。如果日期相同,则按数据排序。
不幸的是,您的阵列结构不正确。如果另一个category = Value_3作为数组的最后一个元素出现怎么办。应该将其与其他Value_3条目分组,还是应该单独排序?根据此答案,应重组数组以简化排序。
另一个改进是日期存储方式。 America date格式完全不能用于字符串或数字值进行排序。可以将其转换为Unix时间戳,也可以使用ISO日期格式" YYYY-MM-DD"。无需费力就可以轻松比较两者。
假设您的数组位于$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"
}
}
我认为您应该针对每种日期应用这种排序。 您创建一个包含各种日期以及按类别和数据排序的数组。 之后,按日期合并数组。
我现在遇到了您的问题,请参阅我的代码。
这行得通,我接受了答案。 但是,通过在0和1之间添加键(对其重新编号)array ("category" => Value_1,"date" => 01022011,"data" => B),它不再起作用。 虐待设法弄清楚。
操作...只需在循环内移动$prevDate和其他命令即可! 现在看我的代码
另外,您需要在if语句中添加&& $index > 0,这可能会因读取越界数据而产生影响。
@CharlesSmith当$index == 0时,$prevData和其他为空,这与$row[data]不同,依此类推...
确实如此; 但是,我特别指的是if ($row[date] > $prevDate)和if ($row[date] == $prevDate && $row[data] < $prevData)。 正如我所说,我的测试是在数组中添加了1 => array ("category" => Value_1,"date" => 01022011,"data" => B),。
此代码可为您测试。
让我们继续聊天中的讨论