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

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

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),。

此代码可为您测试。

让我们继续聊天中的讨论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值