PHP有限的foreach

时间:2016-02-07 13:40:00

标签: php json foreach

我的array包含来自JSON文件的大量数据,使用json_decode,我希望使用foreach循环数据。

示例

$json = file_get_contents('data.json');
$data = json_decode(preg_replace('/(\])\](\R)\[/', '$1,$2', $json));

现在我只是为了逐个获取数据

foreach($data as $d){
  ...
}

但是foreach似乎有限,它没有给我文件的所有数据,但只有其中的一些,我不明白为什么,任何想法为什么以及如何解决这个问题?

原始字符串:(无效的JSON) https://paste.ee/r/RN7rK
修改后的结构和json_decode结果 (using print_r):我无法发布,它太大,请尝试我的preg_replace,然后{{1} }

2 个答案:

答案 0 :(得分:1)

您的JSON解码数组中有7516条记录。

此记录集有两个不同的部分:

  • 6970条记录的第一部分包含22个元素的记录,第一部分的值为“s”。第一次出现是这样的:

    ["s","13","shelves_norja","49500","0","1","1","#ffffff,#F7EBBC",
     "Beige Bookcase", "For nic naks and books.","","5", "true", "-1",
     "false","","1","true","0","0","0","false"]
    
  • 546的第二部分包含19个元素的记录,第一部分的值为“i”。第一次出现:

    ["i","1", "post.it",      "0",    "", "", "", "",
     "Pad of stickies","Pad of stickies",        "","-1","false","-1",
     "false","","5","false",           "false"]
    

我在最后一个记录的最后一个元素之前添加了空格,以突出显示差异:

第一种类型在最后一个字段之前有3个数字字段,缺少第二种记录类型。

因此,在您的代码中,您需要测试数组元素的数量,并为这三个元素提供默认值。

您可以使用以下代码实现此目的:

foreach ($data as $d){
    if (count($d) == 19) {
        array_splice($d, 18, 0, array("0", "0", "0"));
    }
    // rest of your code
}

这会将三个“缺失的”元素注入到19个元素的数组中,这样它们就可以获得与其他元素相同的结构。

或者,你可以做相反的事情,并从较长的数组值中删除这三个元素,但要注意这些元素并不总是包含零,这样你就会有效地丢失信息。 / p>

但是,正如您在评论中所说,您缺少大约7000条记录,这表明您在处理较长的阵列时遇到问题。如果您想使用此替代方案,您的代码将变为:

foreach ($data as $d){
    if (count($d) == 22) {
        array_splice($d, 18, 3);
    }
    // rest of your code
}

答案 1 :(得分:0)

执行此测试的记录为7516:

/* My original json manipulation:  */                                       # 01
if( 1 )
{
    $json = preg_replace('/[\n\r\t]/','',$json);
    $json = str_replace( '][', '],[', $json );
    $json = preg_replace( '/\[\[+/', '[', $json );
    $json = preg_replace( '/\]\]+/', ']', $json );
    $json = "[$json]";
}
/* Your original json manipulation:  */
else
{
    $json = preg_replace('/(\])\](\R)\[/', '$1,$2', $json);
}

$data = json_decode( $json );                                               # 02

/* Inverse test:  */
$lost = 0;
foreach( $data as $row )
{
    $enc = json_encode( $row );
    if( FALSE===strpos( $json, $enc ) ) $lost++;                            # 03
    else $json = str_replace( $enc, '', $json );
}
$json  = preg_replace('/],,+\[/','],[',$json);                              # 04
$found = explode( '],[',$json );

echo "Total: ".count($data).PHP_EOL;
echo "Lost:  $lost".PHP_EOL;
echo "Found: ".count($found).PHP_EOL;

在步骤#01 ,您可以找到我的json操作。它可以缩短,但为了清楚起见我留下了它。您可以将if( 1 )更改为if( 0 )以应用正则表达式。

在json解码(#02 )之后,我执行了一个反向测试:我处理每个解码后的数组值,在json中重新编码它并搜索它们是否存在于json字符串中(# 03 ):如果它们存在,我会从json字符串中删除它,否则我会增加$lost变量。

foreach循环之后,我在转换后的json字符串中减少多次出现,,然后在数组中将其],[拆分。

最后,我打印解码的json中的项目总数,丢失的项目总数和修改后的json的总行数。 使用我的操作,结果是'Lost:65,Found:65',使用你的操作结果是'Lost:65,Found:45'(但我没有重新编辑最终的json转换)。< / p>

鉴于Lost / Found的数量是相同的,我认为很可能没有元素保持未解码,但如果你想要,你可以执行更准确的检查,将$lost声明为数组,然后,在#03 ,以这种方式更改行:

if( FALSE===strpos( $json, $enc ) ) $lost[] = $enc;

然后,在foreach循环结束时:

(...)
$found = explode( '],[',$json );
print_r( $lost );
print_r( $found );

然后手动检查是否每个未找到的项目在剩余的修改过的json中都有相应的值。

PS:由于编码特殊字符问题,它们是“丢失”的记录。