PHP while looping through arrays
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("$DOCUME开发者_如何学编程NT_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;
}
}
}
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;
}
}
}
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] );
}
}
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
精彩评论