仅当日期值连续时才按多列对二维数组的行进行分组
如果除 startdate
之外的所有值都相同,我想要合并多个关联数组。如果两个数组确实相同,我想合并它们并创建一个新元素 enddate
,以便 startdate
和 enddate
显示日期范围。该范围内的所有日期都必须在原始数组中表示,即如果缺少日期,则不得合并其两侧的日期。
Array('color'=>'red','size'=>'large','shape'=>'circle','startdate'=>'2011-08-17')
Array('color'=>'red','size'=>'large','shape'=>'circle','startdate'=>'2011-08-18')
Array('color'=>'red','size'=>'large','shape'=>'square','startdate'=>'2011-08-20')
应该变成:
Array('color'=>'red','size'=>'large','shape'=>'circle','startdate'=>'2011-08-17','enddate'=>'2011-08-18')
Array('color'=>'red','size'=>'large','shape'=>'square','startdate'=>'2011-08-20')
到目前为止,我已经尝试循环遍历每个数组并创建一个多维数组:
foreach($arrays as $id => $array){
$mergearray[$array['red']][$array['large']][$array['circle']] = $id;
}
以便检查另一个数组是否具有相同的值。我正在尝试使用这些数组来重建原始结构中的数组。
I have multiple associative arrays that I want to merge if all values except startdate
are the same. If two arrays are indeed the same, I want to merge them and create a new element enddate
so that startdate
and enddate
show the date range. All dates within the range must be represented in the original arrays, i.e. if a date is missing, the dates on either side of it must not be merged.
Array('color'=>'red','size'=>'large','shape'=>'circle','startdate'=>'2011-08-17')
Array('color'=>'red','size'=>'large','shape'=>'circle','startdate'=>'2011-08-18')
Array('color'=>'red','size'=>'large','shape'=>'square','startdate'=>'2011-08-20')
should become:
Array('color'=>'red','size'=>'large','shape'=>'circle','startdate'=>'2011-08-17','enddate'=>'2011-08-18')
Array('color'=>'red','size'=>'large','shape'=>'square','startdate'=>'2011-08-20')
So far I have tried looping through each array and creating a multidimensional array:
foreach($arrays as $id => $array){
$mergearray[$array['red']][$array['large']][$array['circle']] = $id;
}
in order to check whether another array has the same values. I'm trying to use those arrays to reconstruct arrays in the original structure.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
避免使用日期/日期函数,这是浪费 CPU 时间,没有任何额外的好处(戴夫的回答)。
避免大量使用数组函数(adlawson 的回答),同样浪费时间,只需以智能方式排序数组和处理就会快得多。
但最重要的是,你想做什么,为什么这些数组是这样的,以及......这一切背后是否有 SQL ?
因为如果有的话,有比尝试合并格式错误的数组更简单的解决方案(恕我直言,您寻求的转换意味着在某个时刻出了问题。start_time 变成 end_time 表示尝试保留完整的项目历史,在 PHP 本身中没有地位(恕我直言)。
如果确实是您需要的,我会给您正确的 PHP 代码,但我很怀疑这是否是您应用程序前进的正确方法。
Avoid the day/ date functions it's a waste of cpu time for no added benefit (answer from Dave).
Avoid the massive array function use (answer from adlawson), same waste of time, just ordering arrays and processing the smart way will be much faster.
But mostly, what are you trying to do, why are those arrays like that and ... is there an SQL behind all that ?
Because if there is, there's much simpler solutions than attempting to merge badly-formed arrays (with all due respect, the transformation you seek implies that something went wrong at some point.. a start_time becoming an end_time denotes an attempt at keeping a full item history, which has no place in PHP itself imho).
I'll give you the right PHP code if it really is what you need but I have quite a doubt it's the correct way to go forward for your application.
像这样的事情应该可以解决问题:
Something like this should do the trick:
我看不到这种合并的实际实现,但这应该可行。它可能看起来很冗长,但它会处理一些事情。
I can't see the actual implementation of such a merge, but this should work. It may look long winded, but it takes care of a few things as it goes.
鉴于您已经有一个数组数组,您实际上要做的是删除连续条目(每个时间跨度的第一个条目除外)。
您的算法将是:
这基本上是戴夫·柴尔德答案的更简单、更到位的版本。
Given that you have an array of arrays already, what you're actually trying to do is DELETE consecutive entries (other than the first entry for each time span).
Your algorithm would be:
This is basically a more minimal, and in-place version of Dave Child's answer.
假设元素已按日期排序。如果不是,您可以
在将其传递给
group_and_sort($data)
之前使用:。Assumes the elements are already sorted by date. If they're not, you could use:
prior to passing it to
group_and_sort($data)
.确保您的输入数据至少按
startdate
值排序。迭代行,并使用由 3 个标识列构建的字符串来确定分组。
如果第一次遇到某个组,或者当前行没有紧随专用组的最后一个日期,则开始一个新组。
如果多次遇到某个组并且具有连续的日期,则将该新日期写入新的
结束日期
。使用引用可以防止需要跟踪先前的值已被推入结果数组的位置。 演示
Ensure that your input data is at least sorted by
startdate
values.Iterate over the rows, and use a string built from the 3 identifying columns to determine the grouping.
If a group is encountered for the first time or the current row does not immediately follow the last date of the dedicated group, then start a new group.
If a group is encountered more than once and has a consecutive date, then write that new date as the new
enddate
.Using references prevents needing to keep track of where previous values have been pushed into the result array. Demo