PHP 循环数组时

发布于 2024-12-05 15:14:57 字数 2323 浏览 0 评论 0原文

大家好,我在正确嵌套 while 循环以从 2 个数组读取数据时遇到问题。 我有 2 个文件,从中读取内容:

file1: item_list.txt
string1 \n
string2 \n
string3 \n
...

file2: item+info.txt
string3 \t info1 \t info2 \t info3
string1 \t info7 \t info1 \t info4
string5 \t info2 \t info3
string2 \t info2 \t info4 \t info1

(值仅由换行符和制表符分隔,我在此处的字符之间添加了一个空格只是为了提高可读性)

我使用 fgetcsv() 函数从文件中读取数据,文件中的每一行都作为数组存储到变量 $data 中。我创建了一个带有条件 (!feof($fp))while 循环来读取文件直到最后一行。但我不能完全正确地嵌套第二个循环。

我想用这个做什么: 读取 file1 中找到的第一个字符串,转到 file2 并尝试查找该字符串。如果存在匹配项,则获取该字符串的信息数据(所有数据或仅一个数据并不重要)。如果不匹配,则返回消息“no match”。无论哪种情况,一旦第二个循环完成,我需要读取 file1 中的第二个字符串,然后再次在 file2 中进行搜索。只要有东西可以从文件中读取,就重复此操作1。

这是我的代码的两个版本,它们不起作用,我不明白为什么。

//opening the files
$fp = fopen("$DOCUMENT_ROOT/test/item_list.txt", "r"); #raw item list
$pf = fopen("$DOCUMENT_ROOT/test/item+info.txt", "r"); #item+info list

//read from first file
$line=0;
while (!feof($fp)){
    $line++;
    $data1 = fgetcsv($fp, "1000", "\n");
    $item1= $data1[0];
    echo "line: $line. item_list: ".$item1; //just to see on screen what's happening
    print_r($data1); //same here, just to see what's going on
    echo"<br />";

    //searching for string in file2
    $row=0;
    while (!feof($pf)){
        $row++;
        $data2 = fgetcsv($pf, "1000", "\t");
        $item2= $data2[0];
        echo "line: $row. item+info: ".$item2; //just checking things on screen
        print_r($data2); //here too
        echo "<br />";

        //conditioning
        //equal strings
        if ($string1== $string2)
            echo $data2[1]."<br />";
        break;
    }
}

fclose($fp);
fclose($pf);

过去,只要 item_list.txt 和 item+info.txt 中的项目是有序的
完全相同 (string1\nstring2\string3 ->
string1\tinfo1\nstring2\tinfo2\nstring3\tinfo3 - 但这永远不会发生在我的 在这种情况下,不可能像这样订购项目)

我尝试使用 foreach() 语句执行数组迭代,但结果是我无法理解的。

while (!feof($fp)){
    $data1 = fgetcsv($fp);
    foreach ($data1 as $token1) {
        while (!feof($pf)) {
            $data2 = fgetcsv($pf);
            foreach ($data2 as $value) {
                explode ("\t", $value);
                if ($token1 == $value[0])
                    echo $value[1];
            } 
            break;
        } 
    }
}

Hy everyone, I'm having trouble with properly nesting while loops to read from 2 arrays.
I have 2 files from which I read the content:

file1: item_list.txt
string1 \n
string2 \n
string3 \n
...

file2: item+info.txt
string3 \t info1 \t info2 \t info3
string1 \t info7 \t info1 \t info4
string5 \t info2 \t info3
string2 \t info2 \t info4 \t info1

(values are separated by new lines and tabs only, I added one space between characters here just to increase readability).

I read from files using fgetcsv() function, and each row from file is stored as an array into a variable $data. I created a while loop with condition (!feof($fp)) to read through the file until the last row. But I can't quite properly nest the second loop.

What I want to do with this:
read the first string found in file1, go to file2 and try to find that string. If there's a match, get the info data for that string (all of the data, or just one, doesn't matter). If there's no match, return message "no match". In either case, once the second loop has done it's thing, I need to read the second string in file1, and do the search in file2 again. Repeat this as long as there is something to read from the file1.

here are two versions of my code, they don't work, and I can't figure out why.

//opening the files
$fp = fopen("$DOCUMENT_ROOT/test/item_list.txt", "r"); #raw item list
$pf = fopen("$DOCUMENT_ROOT/test/item+info.txt", "r"); #item+info list

//read from first file
$line=0;
while (!feof($fp)){
    $line++;
    $data1 = fgetcsv($fp, "1000", "\n");
    $item1= $data1[0];
    echo "line: $line. item_list: ".$item1; //just to see on screen what's happening
    print_r($data1); //same here, just to see what's going on
    echo"<br />";

    //searching for string in file2
    $row=0;
    while (!feof($pf)){
        $row++;
        $data2 = fgetcsv($pf, "1000", "\t");
        $item2= $data2[0];
        echo "line: $row. item+info: ".$item2; //just checking things on screen
        print_r($data2); //here too
        echo "<br />";

        //conditioning
        //equal strings
        if ($string1== $string2)
            echo $data2[1]."<br />";
        break;
    }
}

fclose($fp);
fclose($pf);

this used to work as long as the items in item_list.txt and item+info.txt are oredered
exactly the same (string1\nstring2\string3 ->
string1\tinfo1\nstring2\tinfo2\nstring3\tinfo3 - but that's never going to happen in my
case, it's impossible to order the items like that)

I tried to do it with foreach() statement do itterate through arrays, but the result is something that I can't make any sense out of.

while (!feof($fp)){
    $data1 = fgetcsv($fp);
    foreach ($data1 as $token1) {
        while (!feof($pf)) {
            $data2 = fgetcsv($pf);
            foreach ($data2 as $value) {
                explode ("\t", $value);
                if ($token1 == $value[0])
                    echo $value[1];
            } 
            break;
        } 
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薆情海 2024-12-12 15:14:57

这应该可以做到:

$file1 = file($DOCUMENT_ROOT . '/test/item_list.txt');
$file2 = file($DOCUMENT_ROOT . '/test/item+info.txt');

foreach ($file1 as $line)
{
    $line = rtrim($line); // just in case ...
    if ($line === '') continue;

    foreach($file2 as $infoline)
    {
        $infoline = explode("\t", rtrim($infoline);
        if ($line === $infoline[0])
        {
            array_shift($infoline);
            echo $line . '<br /><br />' . implode('<br />', $infoline);
            // $results[$line] = $infoline; // uncomment this if you need the search results stored for later use
            break;
        }
    }
}

This should do it:

$file1 = file($DOCUMENT_ROOT . '/test/item_list.txt');
$file2 = file($DOCUMENT_ROOT . '/test/item+info.txt');

foreach ($file1 as $line)
{
    $line = rtrim($line); // just in case ...
    if ($line === '') continue;

    foreach($file2 as $infoline)
    {
        $infoline = explode("\t", rtrim($infoline);
        if ($line === $infoline[0])
        {
            array_shift($infoline);
            echo $line . '<br /><br />' . implode('<br />', $infoline);
            // $results[$line] = $infoline; // uncomment this if you need the search results stored for later use
            break;
        }
    }
}
怼怹恏 2024-12-12 15:14:57

这是一个粗略的描述:

$filename1 = 'item_list.txt';
$filename2 = 'item+info.txt';

# Init the Raw Array
$content2raw = array();

# Get the File Contents for File 2
$file2 = file_get_contents( $filename2 );
# Split it into an Array by Line Breaks
$content2raw = preg_split( "/\n/" , $file2 , -1 , PREG_SPLIT_NO_EMPTY );

# Unset the variable holding the file contents
unset( $file2 );

# Init the Fixed Array
$content2 = array();

# Loop through the Raw Array
foreach( $content2raw as $l ){
  // Each Line of Filename2
  # Split the Line on Tabs
  $t = preg_split( "/\s*\t\s*/" , $l , -1 );
  # Set the Fixed Array, using the first element from the line as the key
  $content2[ $t[0] ] = $t;
}

# Unset the Raw Array
unset( $content2raw );

# Get the File Contents from File 1
$file1 = file_get_contents( $filename1 );
# Split it into an Array by Line Breaks
$contents1 = preg_split( "/\n/" , $file1 , -1 , PREG_SPLIT_NO_EMPTY );

# Unset the variable holding the file contents
unset( $file1 );

# Loop through the Lines, using each line as the Key to look for
foreach( $content1 as $v ){
  # Check whether a matching element exists in the array from File 2
  if( !array_key_exists( $k , $content2 ) ){
    // No Match Found
    echo 'No Match';
  }else{
    // Match Found
    echo 'Match Found';
    var_dump( $content2[$v] );
  }
}

修正案,根据 @Bluewind 的评论/反馈

$filename1 = 'item_list.txt';
$filename2 = 'item+info.txt';

# Open and Split the file into an Array by Line
$content2raw = file( $filename2 );

# Init the Fixed Array
$content2 = array();

# Loop through the Raw Array
foreach( $content2raw as $l ){
  // Each Line of Filename2
  # Split the Line on Tabs
  $t = preg_split( "/\s*\t\s*/" , $l , -1 );
  # Set the Fixed Array, using the first element from the line as the key
  $content2[ $t[0] ] = $t;
}

# Unset the Raw Array
unset( $content2raw );

# Open and Split the file into an Array by Line
$contents1 = file( $filename1 );

# Loop through the Lines, using each line as the Key to look for
foreach( $content1 as $v ){
  # Check whether a matching element exists in the array from File 2
  if( !array_key_exists( $k , $content2 ) ){
    // No Match Found
    echo 'No Match';
  }else{
    // Match Found
    echo 'Match Found';
    var_dump( $content2[$v] );
  }
}

Here's a rough shot at it:

$filename1 = 'item_list.txt';
$filename2 = 'item+info.txt';

# Init the Raw Array
$content2raw = array();

# Get the File Contents for File 2
$file2 = file_get_contents( $filename2 );
# Split it into an Array by Line Breaks
$content2raw = preg_split( "/\n/" , $file2 , -1 , PREG_SPLIT_NO_EMPTY );

# Unset the variable holding the file contents
unset( $file2 );

# Init the Fixed Array
$content2 = array();

# Loop through the Raw Array
foreach( $content2raw as $l ){
  // Each Line of Filename2
  # Split the Line on Tabs
  $t = preg_split( "/\s*\t\s*/" , $l , -1 );
  # Set the Fixed Array, using the first element from the line as the key
  $content2[ $t[0] ] = $t;
}

# Unset the Raw Array
unset( $content2raw );

# Get the File Contents from File 1
$file1 = file_get_contents( $filename1 );
# Split it into an Array by Line Breaks
$contents1 = preg_split( "/\n/" , $file1 , -1 , PREG_SPLIT_NO_EMPTY );

# Unset the variable holding the file contents
unset( $file1 );

# Loop through the Lines, using each line as the Key to look for
foreach( $content1 as $v ){
  # Check whether a matching element exists in the array from File 2
  if( !array_key_exists( $k , $content2 ) ){
    // No Match Found
    echo 'No Match';
  }else{
    // Match Found
    echo 'Match Found';
    var_dump( $content2[$v] );
  }
}

Amendment, as per comment/feedback from @Bluewind

$filename1 = 'item_list.txt';
$filename2 = 'item+info.txt';

# Open and Split the file into an Array by Line
$content2raw = file( $filename2 );

# Init the Fixed Array
$content2 = array();

# Loop through the Raw Array
foreach( $content2raw as $l ){
  // Each Line of Filename2
  # Split the Line on Tabs
  $t = preg_split( "/\s*\t\s*/" , $l , -1 );
  # Set the Fixed Array, using the first element from the line as the key
  $content2[ $t[0] ] = $t;
}

# Unset the Raw Array
unset( $content2raw );

# Open and Split the file into an Array by Line
$contents1 = file( $filename1 );

# Loop through the Lines, using each line as the Key to look for
foreach( $content1 as $v ){
  # Check whether a matching element exists in the array from File 2
  if( !array_key_exists( $k , $content2 ) ){
    // No Match Found
    echo 'No Match';
  }else{
    // Match Found
    echo 'Match Found';
    var_dump( $content2[$v] );
  }
}
哀由 2024-12-12 15:14:57

这实际上比您想象的要少得多。首先,您读取一个信息文件并从中构建一个哈希表:

foreach(file("info_list") as $line) {
    $line = explode("\t", trim($line));
    $info[$line[0]] = $line;
}

然后迭代项目文件并查看哈希中是否有匹配的条目:

foreach(file("item_list") as $line) {
    $item = trim($line);
    if(isset($info[$item]))
        // we have some info for this item 
    else
        // we have no info for this item
}

基本上就是这样

This is actually much less code than you seem to think. First, you read an info file and build a hash table out of it:

foreach(file("info_list") as $line) {
    $line = explode("\t", trim($line));
    $info[$line[0]] = $line;
}

then you iterate through the items file and look if there are matching entries in the hash:

foreach(file("item_list") as $line) {
    $item = trim($line);
    if(isset($info[$item]))
        // we have some info for this item 
    else
        // we have no info for this item
}

that's basically all about this

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文