0

I have text files in a folder such as f1.txt,f2.txt,....f15.txt. I want to get the combination of them that has a length 2.

The final result should be

{f1.txt, f2.txt}, {f1.txt, f3.txt}....

I used the code

 static IEnumerable<IEnumerable<T>> GetKCombs<T>(IEnumerable<T> list, int length) where T : IComparable { if (length == 1) return list.Select(t => new T[] { t }); return GetKCombs(list, length - 1) .SelectMany(t => list.Where(o => o.CompareTo(t.Last()) > 0), (t1, t2) => t1.Concat(new T[] { t2 })); } 

Then call it from the main method.

string[] files = Directory.GetFiles(@"C:\Users\Downloads\Samples", "*.txt"); IEnumerable<IEnumerable<string>> filescombination = GetKCombs(files, 2); 

But why I got nothing?

EDIT:

 foreach(var x in filescombination) { Console.WriteLine(x); } 

In the immediate window, we have

?x {System.Linq.Enumerable.ConcatIterator<string>} first: null second: null 
2
  • Have you tried actually iterating over x? Commented Apr 6, 2014 at 13:47
  • Yes, I put the breakpoint at "}", which is after Console.WriteLine(x); Commented Apr 6, 2014 at 13:51

2 Answers 2

2

Check that 'files' contains the list of files you expect.

The method is working as expected. Tested in a small test app:

class Program { static void Main(string[] args) { List<int> list = new List<int> { 1, 2, 3, 4 }; IEnumerable<IEnumerable<int>> result = GetKCombs(list, 2); foreach (var line in result) { foreach (var item in line) { Console.Write("{0}, ", item); } Console.WriteLine(); } Console.ReadKey(); } static IEnumerable<IEnumerable<T>> GetKCombs<T>(IEnumerable<T> list, int length) where T : IComparable { if (length == 1) return list.Select(t => new T[] { t }); return GetKCombs(list, length - 1) .SelectMany(t => list.Where(o => o.CompareTo(t.Last()) > 0), (t1, t2) => t1.Concat(new T[] { t2 })); } } 

Edit:

In your code you have:

 foreach(IEnumerable<string> x in filescombination) { Console.WriteLine(x); } 

when you do Console.WriteLine(x) it's equivalent to Console.WriteLine(x.ToString()). Default behaviour of ToString() is to show the name of the object.

The reason why in debug mode you get first: null and second: null is because of the Deferred Execution. Your IEnumerable object doesn't yet know what its value is, until you actually try to use those values, with a ToList() or an iterator, for example.

Sign up to request clarification or add additional context in comments.

5 Comments

I'm afraid you're expecting to see more info from an IEnumearble.ToString() than it's actually willing to show. Change the code to a foreach just like in my example.
No, I used your code, but just got one item "f1.txt".
can you please try in the immediate window: ?x.ToList()
It gave me two files.?x.ToList() Count = 2 [0]: "C:\\Users\\Samples\\f1.txt" [1]: "C:\\Users\\Samples\\f10.txt"
So the data is there. You just weren't seeing it in debug because of the deferred execution.
0

Finally I got it by the code.

 foreach(var x in filescombination) { var y = x.ToList()[0] + ',' + x.ToList()[1]; } 

Because x is

IEnumerable<string> 

We can get the result as:

 IEnumerable<IEnumerable<string>> filescombination = GetKCombs(files,2); List<string> flist = new List<string>(); foreach(var x in filescombination) { var y = x.ToList()[0] + ',' + x.ToList()[1]; flist.Add(y); } 

Comments