所有这些都在关联数组中。
我有一个数组,它保存一些ID作为键,保存一些整数作为值:
array([24]=>1620, [49]=>1620, [35]=>1622, [101]=>1623, [214]=>1630, [50]=>1638, [5]=>1640)
我想要获得的是,当"LastValue-FirstValue<=4"时,将所有接近值设置为其中的最高值,如下所示:
array([24]=>1623, [49]=>1623, [35]=>1623, [101]=>1623, [214]=>1630, [50]=>1640, [5]=>1640)
事实上是关于一些有计划日期的事件;该计划日期被存储为周号;我想把一个月内到最后一周的连续个人项目分组。
所以我创建了这个数组,其中包含事件的ID和日期;数组按值升序排列。但我不知道如何在一个月内对连续的单个值进行分组,将它们设置为最高值(最后一个),然后传递到下一个值,识别组,设置值,等等
有什么建议吗?谢谢
当您有一系列没有间隔的长周时,您描述的方法是不明确的。在这种情况下,有几种方法可以将几周分组在一起,保持分组的第一周和最后一周的间隔不应超过4周。
假设你不期望有这么长的一系列不间断的周数,我在这里提出了一个算法,它可以向后遍历(排序的)事件数组。它暂时将周数转换为"绝对"周数,每年不会重置为1,而是不断增加。这样,算法就可以同样地找到跨越年份界限的组:
// Sample data
$data = array(24=>1620, 49=>1620, 35=>1622, 101=>1623, 214=>1630, 50=>1638, 5=>1640);
$last_abs_week = 99999;
$date = new DateTime();
// first week in the "absolute" week numbering:
$ref_date = new DateTime();
$ref_date->setISODate(2000, 1);
// Loop backwards:
foreach (array_reverse(array_keys($data)) as $event) {
$week = $data[$event];
// Get date corresponding to week number
$date->setISODate("20" . substr($week, 0, 2), substr($week, 2));
// Convert date to number of weeks since year 2000 to allow week numbers
// to be subtracted even when belonging to different years
$abs_week = $date->diff($ref_date)->format("%a") / 7;
if ($abs_week < $last_abs_week - 4) {
// Not within same group: start a new group
$last_week = $week;
$last_abs_week = $abs_week;
} else {
// In same group: assign last week of group
$data[$event] = $last_week;
}
}
print_r ($data);
样本数据的输出为:
Array
(
[24] => 1623
[49] => 1623
[35] => 1623
[101] => 1623
[214] => 1630
[50] => 1640
[5] => 1640
)
正向搜索
这里有一种替代方法,按照给定的顺序扫描阵列:
$first_abs_week = 0;
$group = [];
$date = new DateTime();
$ref_date = new DateTime();
$ref_date->setISODate(2000, 1);
foreach ($data as $event => $week) {
// Get date corresponding to week number
$date->setISODate("20" . substr($week, 0, 2), substr($week, 2));
// Convert date to number of weeks since year 2000 to allow week numbers
// to be subtracted even when belonging to different years
$abs_week = $date->diff($ref_date)->format("%a") / 7;
if (count($group) && $abs_week > $first_abs_week + 4) {
$week = $data[array_pop($group)];
foreach ($group as $prev_event) {
$data[$prev_event] = $week;
}
$group = [];
$first_abs_week = $abs_week;
}
$group[] = $event;
}
print_r ($data);
示例数据的输出与第一个备选方案的输出相同。