user3582072
user3582072

Reputation: 67

multiple foreach loops inside while loop

is it possible to include multiple "foreach" statements inside any of the looping constructs like while or for ... i want to open the .wav files from two different directories simultaneously so that i can compare files from both. here is what i am trying to so but it is certainly wrong.. any help in this regard is appreciated.

string[] fileEntries1 = Directory.GetFiles(folder1, "*.wav");
string[] fileEntries2 = Directory.GetFiles(folder11, "*.wav");
while ( foreach(string fileName1 in fileEntries1) && foreach(string fileName2 in fileEntries2))

Upvotes: 2

Views: 181

Answers (6)

danish
danish

Reputation: 5600

Something like this since you only need to validate same file names:

IEnumerable<string> fileEntries1 = Directory.GetFiles(folder1, "*.wav").Select(x => Path.GetFileName(x));
IEnumerable<string> fileEntries2 = Directory.GetFiles(folder2, "*.wav").Select(x => Path.GetFileName(x));

IEnumerable<string> filesToIterate = (fileEntries1.Count() > fileEntries2.Count()) ? fileEntries1 : fileEntries2;
IEnumerable<string> filesToValidate = (fileEntries1.Count() < fileEntries2.Count()) ? fileEntries1 : fileEntries2;

// Iterate the bigger collection
foreach (string fileName in filesToIterate)
{
    // Find the files in smaller collection
    if (filesToValidate.Contains(fileName))
    {
        // Get actual file and compare
    }
    else
    {
        // File does not exist in another list. Handle appropriately
    }
}

.Net 2.0 based solution:

List<string> fileEntries1 = new List<string>(Directory.GetFiles(folder1, "*.wav"));

List<string> fileEntries2 = new List<string>(Directory.GetFiles(folder2, "*.wav"));

List<string> filesToIterate = (fileEntries1.Count > fileEntries2.Count) ? fileEntries1 : fileEntries2;
filesToValidate = (fileEntries1.Count < fileEntries2.Count) ? fileEntries1 : fileEntries2;

string iteratorFileName;
string validatorFilePath;

// Iterate the bigger collection
foreach (string fileName in filesToIterate)
{
    iteratorFileName = Path.GetFileName(fileName);

    // Find the files in smaller collection
    if ((validatorFilePath = FindFile(iteratorFileName)) != null)
    {
        // Compare fileName and validatorFilePath files here
    }
    else
    {
        // File does not exist in another list. Handle appropriately
    }
}

FindFile method:

static List<string> filesToValidate;

private static string FindFile(string fileToFind)
{
    string returnValue = null;

    foreach (string filePath in filesToValidate)
    {
        if (string.Compare(Path.GetFileName(filePath), fileToFind, true) == 0)
        {
            // Found the file
            returnValue = filePath;
            break;
        }
    }

    if (returnValue != null)
    {
        // File was found in smaller list. Remove this file from the list since we do not need to look for it again
        filesToValidate.Remove(returnValue);    
    }

    return returnValue;    
}

You may or may not choose to make fields and methods static based on your needs.

Upvotes: 0

Tolga Evcimen
Tolga Evcimen

Reputation: 7352

I like this kind of statements in one line. So even though most of the answers here are correct, I give you this.

string[] fileEntries1 = Directory.GetFiles(folder1, "*.wav");
string[] fileEntries2 = Directory.GetFiles(folder11, "*.wav");

foreach( var fileExistsInBoth in fileEntries1.Where(fe1 => fileEntries2.Contains(fe1) )
{
    /// here you will have the records which exists in both of the lists
}

Upvotes: 1

dcastro
dcastro

Reputation: 68640

If you want to enable both collections "in parallel", then use their iterators like this:

var fileEntriesIterator1 = Directory.EnumerateFiles(folder1, "*.wav").GetEnumerator();
var fileEntriesIterator2 = Directory.EnumerateFiles(folder11, "*.wav").GetEnumerator();

while(fileEntriesIterator1.MoveNext() && fileEntriesIterator2.MoveNext())
{
    var file1 = fileEntriesIterator1.Current;
    var file2 = fileEntriesIterator2.Current;
}

If one collection is shorter than the other, this loop will end when the shorter collection has no more elements.

Upvotes: 0

Bathsheba
Bathsheba

Reputation: 234655

Gramatically speaking no. This is because a foreach construct is a statement whereas the tests in a while statement must be expressions.

Your best bet is to nest the foreach blocks:

foreach(string fileName1 in fileEntries1)
{
    foreach(string fileName2 in fileEntries2)

Upvotes: 2

Gawie Schneider
Gawie Schneider

Reputation: 1150

This is what I would suggest, using linq

using System.Linq;

var fileEntries1 = Directory.GetFiles(folder1, "*.wav");
var fileEntries2 = Directory.GetFiles(folder11, "*.wav");
foreach (var entry1 in fileEntries1)
{
    var entries = fileEntries2.Where(x => Equals(entry1, x));
    if (entries.Any())
    {
        //We have matches
        //entries is a list of matches in fileentries2 for entry1
    }
}

Upvotes: 0

Codor
Codor

Reputation: 17605

If you want to iterate all pairs of files in both paths respectively, you can do it as follows.

string[] fileEntries1 = Directory.GetFiles(folder1, "*.wav");
string[] fileEntries2 = Directory.GetFiles(folder11, "*.wav");

foreach(string fileName1 in fileEntries1)
{
    foreach(string fileName2 in fileEntries2)
    {
        // to the actual comparison
    }
}

Upvotes: 0

Related Questions