Find common items in a list of lists of strings

Hi I have allLists which contains lists of strings. I want to find common elements among these string lists. I tried

var intersection = allLists
  .Skip(1)
  .Aggregate(
  new HashSet<string>(allLists.First()),
  (h, e) => { h.IntersectWith(e); return h);`

      

as well as intersection (hardcoded lists by index), they all didn't work when I tried

var inter = allLists[0].Intersect(allLists[1]).Intersect(allLists[2])
     .Intersect(allLists[3]).ToList();

foreach ( string s in inter) Debug.WriteLine(s+"\n ");

      

So how am I going to do it dynamically and get generic string items in lists; is there a way to avoid Linq?

+3


source to share


2 answers


I would do it like this:

class Program
{
    static void Main(string[] args)
    {
        List<string>[] stringLists = new List<string>[] 
        { 
            new List<string>(){ "a", "b", "c" },
            new List<string>(){ "d", "b", "c" },
            new List<string>(){ "a", "e", "c" }
        };

        // Will contian only 'c' because it the only common item in all three groups.
        var commonItems = 
            stringLists
            .SelectMany(list => list)
            .GroupBy(item => item)
            .Select(group => new { Count = group.Count(), Item = group.Key })
            .Where(item => item.Count == stringLists.Length);

        foreach (var item in commonItems)
        {
            Console.WriteLine(String.Format("Item: {0}, Count: {1}", item.Item, item.Count));
        }
        Console.ReadKey();
    }
}

      

An element is a common element if it occurs in all groups, therefore, the condition that its counter must be equal to the number of groups:

.Where(item => item.Count == stringLists.Length)

      



EDIT:

I should have used HashSet

both in the question. For lists, you can replace the line SelectMany

with the following:

.SelectMany(list => list.Distinct())

      

0


source


Isn't this the easiest way?

var stringLists = new List<string>[] 
    { 
        new List<string>(){ "a", "b", "c" },
        new List<string>(){ "d", "b", "c" },
        new List<string>(){ "a", "e", "c" }
    };

var commonElements =
    stringLists
        .Aggregate((xs, ys) => xs.Intersect(ys).ToList());

      



I get a list with just "c"

in it.

This also handles the case if the items in each list can be repeated.

+2


source







All Articles