我有以下数组:
(
[0] => Array
(
[schedules] => Array
(
[monday] => 1
[tuesday] => 1
[wednesday] => 1
[thursday] => 1
[friday] => 1
[saturday] => 0
[sunday] => 1
)
)
)
我想对第一个关键是明天这个数组的元素进行排序。让我们说今天是星期三。我希望我的数组看起来像这样:
(
[0] => Array
(
[schedules] => Array
(
[thursday] => 1
[friday] => 1
[saturday] => 0
[sunday] => 1
[monday] => 1
[tuesday] => 1
[wednesday] => 1
)
)
)
我已经有了工作日(例如字符串'星期四')。它被传递到我正在使用的函数中。
有关实现此类排序的任何建议吗?谢谢!
答案 0 :(得分:5)
如果您将当天转换为0-6,那么您可以多次array_shift
和array_push
将前几天移动到数组的末尾。
答案 1 :(得分:3)
尝试使用uksort()
。您可以比较链接中描述的回调函数中的日期。
例如:
function compare($a, $b) {
date(strtotime($a)) - date(strtotime($b));
}
uksort($array, "compare");
答案 2 :(得分:3)
您可以通过date功能获取星期几。星期日是0,星期一是1,等等。
$weekday = date("w");
然后,我建议使用uksort函数对数组进行相对于其键的排序,这将回调函数作为排序指南。
uksort($schedules, function ($a, $b) use ($weekday) {
// convert each day to a number 0-6 and compare to $weekday
});
答案 3 :(得分:2)
您可以这样做来实现
$week = [
'sunday',
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
];
$day = date('w'); // weekday as integer(3 for Wednesday)
for ($i=0; $i <= $day ; $i++) {
array_push($week, array_shift($week));
}
$result = $week;
结果(如果今天是星期三):
Array
(
[0] => thursday
[1] => friday
[2] => saturday
[3] => sunday
[4] => monday
[5] => tuesday
[6] => wednesday
)
答案 4 :(得分:1)
首先,您需要一个正确顺序的列表,您可以通过DateTime类获取该列表。然后,当您遍历旧数组时,使用正确的顺序作为键对数组进行排序,如下所示:
function sort_by_weekday( $input_array) {
$now = new DateTime( "tomorrow", new DateTimeZone('America/New_York'));
$interval = new DateInterval( 'P1D'); // 1 Day interval
$period = new DatePeriod( $now, $interval, 7); // 7 Days
$sorted_array = array();
foreach( $period as $day) {
$weekday = strtolower( $day->format( 'l'));
foreach( $input_array as $key => $value) {
$sorted_array[ $key ][ $weekday ] = $value[ $weekday ];
}
}
return $sorted_array;
}
您可以在the demo中看到它。
答案 5 :(得分:1)
如果将uksort与简单函数结合使用,这是一个非常简单的解决方案。
显然需要将日期名称字符串转换为整数,但如果当天在当前工作日之前,只需向变量添加七,这将保证数组按“后”排序,即使日期为一周意味着否则。
<?php
$a='sunday'; // Example Input
$b='saturday'; // Example Input
function funnyDateCompare($a, $b)
{
$a=date('w',strtotime($a));
$b=date('w',strtotime($b));
if($a<=date('w'))
{
$a+=7;
// First value is less than or equal to today.
// Adding 7 to the answer.
}
return ($a - $b);
}
uksort($array, "funnyDateCompare")
?>
答案 6 :(得分:0)
我写了一个解决方案,它不会将日期转换为日期/时间类型,而是使用闭包和uksort。从本质上讲,传递给uksort的每个键都与“明天”键的位置进行比较,如果明天是“之前”,则将其“提升”到未来(+= 7
),然后一个简单的比较结果是使用
编辑由@nickb发表评论(谢谢!)
<?php
function sortedWithNext($days, $tomorrow) {
$index_dictionary = array_combine(array_keys($days), range(0,6));
$index_of_tomorrow = $index_dictionary[$tomorrow];
$compare_function = function($k1, $k2) use ($index_dictionary, $index_of_tomorrow) {
$index_of_k1 = $index_dictionary[$k1];
$index_of_k2 = $index_dictionary[$k2];
if($index_of_k1 < $index_of_tomorrow)
$index_of_k1 += 7;
if($index_of_k2 < $index_of_tomorrow)
$index_of_k2 += 7;
return $index_of_k1 - $index_of_k2;
};
uksort($days, $compare_function);
return $days;
}
$daysPool = array(
'monday'=>1,
'tuesday'=>1,
'wednesday'=>1,
'thursday'=>1,
'friday'=>0,
'saturday'=>1,
'sunday'=>1,
);
$tomorrow = 'thursday';
$sortedDays = sortedWithNext($daysPool, $tomorrow);
var_dump($sortedDays);
我使用100,000次迭代测试,此方法花费大约2.2e-5秒来对数组进行排序。好奇的人会检查这个答案的第一个版本,找到性能较差的版本,花费大约两倍,5.5e-5秒。
答案 7 :(得分:0)
这对我有用,只是一个简单的循环:
$array = array();
$month = date('m');
$day = date('d');
$year = date('Y');
for($i=1; $i<=7; $i++){
$array[] = date('l',mktime(0,0,0,$month,($day+$i),$year));
}
输出数组如下所示:(如果今天是星期二)
array(
(int) 0 => 'Wednesday',
(int) 1 => 'Thursday',
(int) 2 => 'Friday',
(int) 3 => 'Saturday',
(int) 4 => 'Sunday',
(int) 5 => 'Monday',
(int) 6 => 'Tuesday'
)
答案 8 :(得分:0)
此答案允许从哪一天开始,并动态处理天数的标记。
这只是使用uksort(),date()和strtotime()的改进解决方案。
function sort_days( $term1, $term2 ) {
$weekdays = array( 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' );
foreach ( $weekdays as $key => $value ) {
$weekdays[ $key ] = date( 'N', strtotime( $value ) );
}
$term1_time = date( 'N', strtotime( strtolower( $term1 ) ) );
$term2_time = date( 'N', strtotime( strtolower( $term2 ) ) );
return array_search( $term1_time, $weekdays ) - array_search( $term2_time, $weekdays );
}
使用uksort()
对键进行排序$uk_days = array(
'thursday' => 1,
'monday' => 1,
'saturday' => 1,
'wednesday' => 1,
'sunday' => 1,
'friday' => 1,
'tuesday' => 1,
);
uksort($uk_days, "sort_days");
var_dump($uk_days);
使用usort()
对键进行排序$u_days = array(
'thursday',
'monday',
'saturday',
'wednesday',
'sunday',
'friday',
'tuesday',
);
usort($u_days, "sort_days");
var_dump($u_days);
答案 9 :(得分:0)
请尝试以下代码。它将根据当前日期对日期进行排序。
$days = array("Friday","Thursday","Wednesday","Tuesday");
$days = array_combine($days,$days);
//loop the days and check the next day
foreach($days as $k => $dd){
//check next day name & increment current date with +1
$current_dt = date("Y-m-d",strtotime("next day", strtotime($current_dt)));
$days_name = date("l", strtotime($current_dt));
// if day name exists in array, push in seperate array
if(!empty($days[$days_name])){
$arrSortedDays[] = $days_name;
}
}
//check if currnet day fall today, push it in array to last element.
if(!empty($days[date("l")])){
$arrSortedDays[] = date("l");
}
答案 10 :(得分:0)
子数组数据中已经存在循环顺序,因此不需要通过将每个条目相互比较来进行排序。
最直接的解决方案(据我所知)是:
代码:(Demo)
$newStart = 'thursday';
foreach ($array as &$entry) {
$position = array_search(
$newStart,
array_keys($entry['schedules'])
);
if ($position) {
$entry['schedules'] += array_splice(
$entry['schedules'],
0,
$position
);
}
}
var_export($array);
该条件确保在未找到目标键 (false
) 或已在第一个位置 (0
) 时不执行元素轮换。
array_search()
是高效的,因为它在找到第一个匹配项后立即停止迭代。
我不认可任何推荐的早期答案:
uksort()
-- 这具有更大的计算复杂度,更不用说自定义函数体中函数调用的额外开销了。我的解决方案恰好适合作为实用函数,因为它不依赖于任何与日期相关的数据/逻辑。