Подтвердить что ты не робот

Объединение двух IEnumerable <T> s

У меня есть два IEnumerable<T> s.

Один заполняется резервным эльфийном. Это всегда будет содержать большинство элементов. Другой будет заполняться в зависимости от некоторых параметров и, возможно, будет содержать меньше элементов. Если элемент не существует во втором, мне нужно заполнить его эквивалентным первым.

Этот код выполняет задание, но для меня он неэффективен и требует, чтобы я использовал IEnumerables для ILists или использовал временный список Человек реализует 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);  
}

Любые предложения?

4b9b3361

Ответ 1

Попробуйте это.

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)));
}

Ответ 2

translated.Union(fallback)

или (если Лицо не реализует IEquatable<Person> по ID)

translated.Union(fallback, PersonComparer.Instance)

где PersonComparer:

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;
    }
}

Ответ 3

используйте Concat. Union не работает в случае List<dynamic> type