开发者

C# Loop through Files and Repeat Until Every Combination of Comparisons is Complete

I have to perform a t开发者_高级运维ask and I'll do my best to detail it.

I have 5 folders, for example:

  • Folder A
  • Folder B
  • Folder C
  • Folder D
  • Folder E

In each of these folders is a file. Basically, I need to compare each file against one another (I'll be calculating a value based upon data within these files.) This needs to be done for every combination (A to B, A to C, A to D, A to E, B to C, B to D, B to E, C to D, C to E, D to E)

Not really sure where to begin with this. Any help is greatly appreciated!


Something like this should work

var folders = new string[] { "A", "B", "C", "D", "E" };

for (int i = 0; i < folders.Length; i++)
{
  for(int j = i+1; j < folders.Length; j++)
    Console.WriteLine(folders[i] + "=>" + folders[j]);
}

Of course, I'm using a simple string[] for demonstration purposes but I hope you get the concept?


Let's assume you have the FileInfo object for your files already, then you could do something like this:

        List<FileInfo> files = new List<FileInfo>() {};
        foreach (FileInfo fileContentA in files)
        {
            foreach (FileInfo fileContentB in files.Where(
                     x.Name.CompareTo(fileContentA.Name) > 0))
            {
                Compare(fileContentA, fileContentB);
            }
        }


string[] folder = { "A", "B", "C", "D", "E" };

for (int i=0; i<folder.Length; ++i)
   for (int j=i+1; j<folder.Length; ++j)
      compareFolders(folder[i], folder[j]);

You could create an extension method to encapsulate this algorithm for use with any array:

public static class Alg
{
   public static void nonIdentityPermutations<T>(this T[] elements, Action<T, T> action)
   {
      for (int i=0; i<elements.Length; ++i)
         for (int j=i+1; j<elements.Length; ++j)
            action(elements[i], elements[j]);
   }
}

Then you could write:

folder.nonIdentityPermutations( (a,b) => Console.WriteLine(a + " to " + b) );

or:

folder.nonIdentityPermutations(compareFolders);


Not sure what your returning value is, but here's an example of traversing the five folders and appending values to a single string as the final value.
You can build your own logic upon this.

string CompareMyFolders()
{
    string FinalValue = "";
    DirectoryInfo[] folders = new DirectoryInfo[5];
    folders[0] = new DirectoryInfo("C:\\FolderA\\");
    folders[1] = ...;
    folders[2] = ...;
    folders[3] = ...;
    folders[4] = ...;

    for(int i = 0; i < folders.Length - 1; i++)
        for(int j = i + 1; j < folders.Length; j++)
            FinalValue += CompareFolders(folders[i], folders[j]);

    return FinalValue;
}

string CompareFolders(DirectoryInfo folder1, DirectoryInfo folder2)
{
    string value = "";
    // compare the files in both directory
    // append the returning data to the value

    return value;
}


I would suggest to start wit a comparison A to B, A to C, A to D, A to E. Then Go on with B to (C to E), then C to (D and E) and then the only one left is D to E.


How about something like:

var files = Directory.GetFiles(myDir, myExtension, SearchOption.AllDirectories)
                     .OrderBy(f => f)
                     .ToArray();

var comparisons = from file1 in files
                  from file2 in files
                  where StringComparer.Ordinal.Compare(file1, file2) < 0
                  select new {
                                file1, 
                                file2, 
                                Comparison = MyComparison(file1, file2)
                             };

Essentially, what this does is create a binary cartesian product of files with itself, and then filters the tuples in a way that prevents both (A,B) and (B,A) from being selected.

Obviously, the sample code will have to be modified to meet your exact requirements.


One solution

#using system.io        

private void RecurseFiles()
{
    String[] files = Directory.GetFiles(@"c:\dev\", "*.tif", SearchOption.AllDirectories);

    for (int i = 0; i < files.Length; i++)
        for (int j = i+1; j < files.Length; j++)
             CompareFiles(files[i], files[j]);
}


If you compare folders to identify mutually corresponding files, then you deal with 3 keys. 1st key is file name (or other means to identify correspondence of 2 files from different directories). 2nd key is directory (part of file's identity). 3rd key is content of the file (or part of content, or attributes, timestamps, hashes etc).

  • gather all file identities as triplets of keys
  • sort them in single container using keys 1,2,3 in this very order
  • traverse the sorted container by taking subset of file identities by single key#1 value at a time.
  • for each such subset build square table with empty diagonal and empty half, where sides of table are key 2,3 values of identities
  • traverse the resulting triangle in any direction to fill the result table (of same shape) completely
  • accumulate the resulting tables in some final container or keep pushing results to output
  • repeat for next subset until there are no more subsets
  • done


A nested loop would easily do the trick to ensure each file is compared to all the others. Not sure of the c# syntax, but this should give you the basic idea:

for each (file:File in fileArray)
{
   for each (

Edit: Bah! I'm way too slow for this site. Anyone who beat me with an example of a nested loop gets a +1. =D

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜