Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to find common items across multiple lists in C#

Tags:

c#

Given the following:

List<List<Option>> optionLists;

what would be a quick way to determine the subset of Option objects that appear in all N lists? Equality is determined through some string property such as option1.Value == option2.Value.

So we should end up with List<Option> where each item appears only once.

like image 405
JC. Avatar asked Sep 03 '08 04:09

JC.


2 Answers

Ok, this will find the list of Option objects that have a Value appearing in every list.

var x = from list in optionLists
        from option in list
        where optionLists.All(l => l.Any(o => o.Value == option.Value))
        orderby option.Value
        select option;

It doesn't do a "distinct" select so it'll return multiple Option objects, some of them with the same Value.

like image 68
Matt Hamilton Avatar answered Oct 01 '22 09:10

Matt Hamilton


Building on Matt's answer, since we are only interested in options that all lists have in common, we can simply check for any options in the first list that the others share:

var sharedOptions =
    from option in optionLists.First( ).Distinct( )
    where optionLists.Skip( 1 ).All( l => l.Contains( option ) )
    select option;

If an option list cannot contain duplicate entires, the Distinct call is unnecessary. If the lists vary greatly in size, it would be better to iterate over the options in the shortest list, rather than whatever list happens to be First. Sorted or hashed collections could be used to improve the lookup time of the Contains call, though it should not make much difference for a moderate number of items.

like image 27
Emperor XLII Avatar answered Oct 01 '22 10:10

Emperor XLII