我正在寻找一种循环关联数组的方法,但只能在之前的5"状态"是" CLOSED_FOR_SERVICE"以及接下来的5"状态"是" OPEN"
这是我提出的有效的方法,但到目前为止并不优雅。我确信我需要为前一个使用for循环,然后为下一个使用另一个循环,但我似乎无法理解它。
for ($i = 0; $i < count($logRow); $i++) {
if (array_key_exists($i - 1, $logRow)){
if (($logRow[$i]['status'] == "OPEN") && ($logRow[$i - 1]['status'] == "CLOSED_FOR_SERVICE")){
if (array_key_exists($i - 2, $logRow)){
if ($logRow[$i - 2]['status'] == "CLOSED_FOR_SERVICE"){
if (array_key_exists($i - 3, $logRow)){
if ($logRow[$i - 3]['status'] == "CLOSED_FOR_SERVICE"){
if (array_key_exists($i - 4, $logRow)){
if ($logRow[$i - 4]['status'] == "CLOSED_FOR_SERVICE"){
if (array_key_exists($i - 5, $logRow)){
if ($logRow[$i - 5]['status'] == "CLOSED_FOR_SERVICE"){
if (array_key_exists($i + 1, $logRow)){
if ($logRow[$i + 1]['status'] == "OPEN"){
if (array_key_exists($i + 2, $logRow)){
if ($logRow[$i + 2]['status'] == "OPEN"){
if (array_key_exists($i + 3, $logRow)){
if ($logRow[$i + 3]['status'] == "OPEN"){
if (array_key_exists($i + 4, $logRow)){
if ($logRow[$i + 4]['status'] == "OPEN"){
if (array_key_exists($i + 5, $logRow)){
if ($logRow[$i + 5]['status'] == "OPEN"){
echo date("F j, Y, g:i a", $logRow[$i]['time']).'<br />';
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
答案 0 :(得分:1)
我没有时间对此进行测试(我会尽快尝试),但这是一般性的想法:
for($i = 0; $i < count($logRow); $i++) {
if($logRow[$i]['status'] == 'OPEN' &&
($prev = array_slice($logRow, $i - 6, 5)) &&
($next = array_slice($logRow, $i + 1, 5)) &&
!array_diff(array_column($prev, 'status'), ['CLOSED_FOR_SERVICE']) &&
!array_diff(array_column($next, 'status'), ['OPEN']))
{
echo date("F j, Y, g:i a", $logRow[$i]['time']).'<br />';
}
}
status
是否已打开status
元素并检查与CLOSED_FOR_SERVICE无差异status
个元素,并检查与OPEN无差异可能更好,只有一个array_column
调用整个数组,除非它是巨大的。
答案 1 :(得分:1)
这是我的想法 不要循环整个阵列。从5开始,在count-4结束,因为在此之前和之后你不会有足够的项目是真的。
Array_slice十个项目并与&#34;模式数组&#34;进行比较。
// i used 0 or 1 instead of closed or open but the idea is the same.
$arr = [0,0,0,1,0,0,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1];
for($i = 5; $i<count($arr)-4;$i++){
if([0,0,0,0,0,1,1,1,1,1] == array_slice($arr, $i-5, 10)){
//echo date("F j, Y, g:i a", $logRow[$i]['time']).'<br />';
echo "yes\n";
}
}
答案 2 :(得分:1)
只是为了好玩,以为我会加入,但做一些完全不同的事情。而不是试图匹配数组而不必担心环绕(如果传递负数,某些数组方法会拾取数组的末尾),我决定尝试匹配字符串......
$mangle = implode(",", array_column($logRow, "status"));
$toFind = trim(str_repeat("CLOSED_FOR_SERVICE,", 5).str_repeat("OPEN,", 5), ",");
$offset = 0;
while ( ($offset = strpos($mangle, $toFind, $offset )) !== false) {
$index = substr_count(substr($mangle, 0, $offset), ",");
$index = array_keys($logRow)[$index+5]; // I do this because I extracted part of the sample data
echo date("F j, Y, g:i a", $logRow[$index]['time']).PHP_EOL;
$offset++;
}
因此它构建了一个包含所有状态的字符串,然后查找5个CLOSED_FOR_SERVICE的字符串,然后查找5个OPEN的字符串。然后它会将逗号计数到它找到此模式的点(添加5,因为这包括5个CLOSED_FOR_SERVICE记录)。
它重复循环,从它停止的地方继续(++确保它不会再次找到相同的那个)。
如果您有一个完整的数组,则不需要array_keys()
,但正如我在评论中提到的,我提取了部分数据,因此有非顺序键。
答案 3 :(得分:-1)
你走了。
for ($i = 5; $i < count($logRow) - 5; $i++) {
$prev = array_slice($logRow, $i - 5, 5);
$next = array_slice($logRow, $i + 1, 5);
if (
5 === count(array_filter($prev, function($row) {
return 'CLOSED_FOR_SERVICE' === $row['status'];
}))
&&
5 === count(array_filter($next, function($row) {
return 'OPEN' === $row['status'];
}))
) {
echo date('F j, Y, g:i a', $logRow[$i]['time']).'<br />';
}
}
答案 4 :(得分:-1)
/* =============================
* PSEUDO CODE
* =============================
*/
// Initialize
open = 0
closed = 0
out = null
//Loop
foreach (array as line) {
// Test for CLOSED_FOR_SERVICE 5 times consecutive occurences
if (closed == 4) {
// Capture target time and jump to next line
if (out == null) {
out = line[time]
continue
}
// Start testing for OPEN statuses and count or reinitialize
if (line[status] == 'OPEN') {
open = open + 1
} else {
out = null
open = 0
closed = 0
continue
}
// Bingo
if (open == 4) {
print out
out = null
open = 0
closed = 0
}
} else {
// Count CLOSED_FOR_SERVICE or reinitialize
closed = line[status] == 'CLOSED_FOR_SERVICE' ? closed + 1 : 0
}
}