The most efficient way to implement what you need is the Aho-Corasick algorithm - if you need to dynamically process the new List 2 items. It is based on the prefix-tree, a commonly used technique in string search algorithms. This algorithm will give you O complexity (sum of all lines)
Another option is the Knuth-Morris-Pratt algorithm , which will give you the same complexity, but initially works with a single search string.
But if you are fine with O((list2.Count*log(list2.Count) + list1.Count*log(list1.Count))*AverageStrLength) , I can offer my simple implementation: Sort both lists. Then follow them at the same time and select matches.
UPDATE: This implementation is great if you have already sorted the lists. Then it runs after about 100 ms. But sorting takes 3.5 seconds, so the implementation is not as good as I expected at the beginning. Regarding a simple implementation, Tim's solution is faster.
list1.Sort(); list2.Sort(); var result = new List<string>(); for(int i=0, j=0; i<list1.Count; i++) { var l1Val = list1[i]; for (; j < list2.Count && string.CompareOrdinal(l1Val, list2[j]) > 0; j++) ; for (; j < list2.Count && list2[j].StartsWith(l1Val); j++) { result.Add(list2[j]); } }
This is the easiest effective implementation I can offer.
source share