2009-11-12 46 views
2

我有兩個序列:使用LINQ查找通用前綴?

IEnumerable<string> x = new[] { "a", "b", "c" }; 
IEnumerable<string> y = new[] { "a", "b", "d", "e" }; 

我想找到這兩個序列(即"a", "b")的公共前綴。有沒有簡潔的方式在LINQ中做到這一點?

請記住,這些不是真的IEnumerable<string>;他們是IEnumerable<PathComponent>,我有一個執行IEqualityComparer<PathComponent>

+1

嗯,4.0得到這個Zip。像x.Zip(y).TakeWhile(t => t.Item1 == t.Item2).Select(t => t.Item1); – Dykam 2009-11-12 10:11:24

+0

+1 yeah Zip會很好地做到這一點。 – 2009-11-12 10:14:30

回答

3

Dykam提到的Zip使我知道這個代碼:

public static class EnumerableExtensions 
{ 
    public delegate bool EqualityComparison<in T1, in T2>(T1 x, T2 y); 
    public delegate bool EqualityComparison<in T>(T x, T y); 

    public static IEnumerable<T> CommonPrefix<T>(
     this IEnumerable<T> xs, 
     IEnumerable<T> ys) 
    { 
     return CommonPrefix(xs, ys, EqualityComparer<T>.Default.Equals); 
    } 

    public static IEnumerable<T> CommonPrefix<T>(
     this IEnumerable<T> xs, 
     IEnumerable<T> ys, 
     EqualityComparison<T> eq) 
    { 
     IEnumerator<T> x = xs.GetEnumerator(); 
     IEnumerator<T> y = ys.GetEnumerator(); 

     while (x.MoveNext() && y.MoveNext() && eq(x.Current, y.Current)) 
     { 
      yield return x.Current; 
     } 
    } 

    public static IEnumerable<TResult> CommonPrefix<T1, T2, TResult> (
     this IEnumerable<T1> xs, 
     IEnumerable<T2> ys, 
     EqualityComparison<T1, T2> eq, 
     Func<T1, T2, TResult> selector) 
    { 
     IEnumerator<T1> x = xs.GetEnumerator(); 
     IEnumerator<T2> y = ys.GetEnumerator(); 

     while (x.MoveNext() && y.MoveNext() && eq(x.Current, y.Current)) 
     { 
      yield return selector(x.Current, y.Current); 
     } 
    } 
} 
+0

Heh,強制要求,放入擴展方法。應該自己做。我實際上在某些Rest庫中爲自己使用ZipSelect。 – Dykam 2009-11-12 21:25:42

0

也許你可以做這樣的事情(未測試):

x.TakeWhile((item, index) => y.Contains(item) && y.IndexOf(item) == index); 

編輯。 IndexOf僅適用於數組,因此應該先將y轉換爲數組。此外,您需要修改代碼以使用您的IEqualityComparer。

1

這工作,但我不知道翻斗的性能()的第二陣列上:

x.TakeWhile((s, i) => y.Skip(i).FirstOrDefault() == s); 

編輯:哎呀 - 這裏有一個更好的方法:

x.TakeWhile((s, i) => y.ElementAt(i) == s); 
+0

@Matt:試過了;除了你需要確保'y'是兩個序列中較長的一個... – 2009-11-12 10:34:21