2009-02-26 2 views
40

私は2つのIEnumerable<T>を持っています。2つのIEnumerableをマージする<T>s

1つは、フォールバック要素で満たされます。これは常に最も多くの要素を含みます。 いくつかのパラメータに応じてもう1つは塗りつぶされ、少ない要素が含まれます。 要素が2番目の要素に存在しない場合は、最初の要素と同等の要素を入力する必要があります。

このコードでは、仕事をしていませんが、私には非効率的な感じとIListsにIEnumerablesをキャストするか、一時リスト 人がIEquatable

IEnumerable<Person> fallBack = Repository.GetPersons(); 
IList<Person> translated = Repository.GetPersons(language).ToList(); 

foreach (Person person in fallBack) 
{ 
    if (!translated.Any(p=>p.equals(person))) 
     translated.add(person); 
} 

任意の提案を実装して使用するように私を必要と? PersonComparerがある

答えて

30

はこれを試してみてください。

public static IEnumerable<Person> SmartCombine(IEnumerable<Person> fallback, IEnumerable<Person> translated) { 
    return translated.Concat(fallback.Where(p => !translated.Any(x => x.id.equals(p.id))); 
} 
+4

これは素晴らしいですが、あなたが気づく必要がある問題があります: http://programmaticallyspeaking.com/how-enumerableconcat-brought-down-a-production-server.html – Oliver

49
translated.Union(fallback) 

か(人がIDによってIEquatable<Person>を実装していない場合)

translated.Union(fallback, PersonComparer.Instance) 

public class PersonComparer : IEqualityComparer<Person> 
{ 
    public static readonly PersonComparer Instance = new PersonComparer(); 

    // We don't need any more instances 
    private PersonComparer() {} 

    public int GetHashCode(Person p) 
    { 
     return p.id; 
    } 

    public bool Equals(Person p1, Person p2) 
    { 
     if (Object.ReferenceEquals(p1, p2)) 
     { 
      return true; 
     } 
     if (Object.ReferenceEquals(p1, null) || 
      Object.ReferenceEquals(p2, null)) 
     { 
      return false; 
     } 
     return p1.id == p2.id; 
    } 
} 
+1

鮮やかな - 彼らが言うように、あなたは毎日何か新しいことを学びます! –

+0

まあ、まだ準備が整っていません... –

+0

Personクラスが正しくEqualityを実装している場合にのみ、それはうまくいきます。 OPによって判断して、私は彼らがないと推測している。 – JaredPar

0

ConcatUnionは動作しませんList<dynamic>タイプ

関連する問題