user1108948
user1108948

Reputation:

Get all combinations of items in an array

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

Upvotes: 0

Views: 392

Answers (2)

user1108948
user1108948

Reputation:

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);
        }

Upvotes: 0

Radu Pascal
Radu Pascal

Reputation: 1337

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.

Upvotes: 2

Related Questions