C # - Поиск общих членов двух List <T>s - Лямбда-синтаксис - PullRequest
4 голосов
/ 15 июля 2009

Итак, я написал это простое консольное приложение, чтобы помочь в моем вопросе. Как правильно использовать лямбда-выражение в строке 3 метода для получения общих членов. Попробовал Join (), но не смог понять правильный синтаксис. Как выяснить ... есть ли не-LINQ способ сделать это в одной строке, которую я пропустил?

class Program
{
    static void Main(string[] args)
    {
        List<int> c = new List<int>() { 1, 2, 3 };
        List<int> a = new List<int>() { 5, 3, 2, 4 };
        IEnumerable<int> j = c.Union<int>(a);
        // just show me the Count
        Console.Write(j.ToList<int>().Count.ToString());

    }
}

Ответы [ 2 ]

20 голосов
/ 15 июля 2009

Вы хотите Intersect():

IEnumerable<int> j = c.Intersect(a);

Вот пример OrderedIntersect(), основанный на идеях, упомянутых в комментариях. Если вы знаете, что ваши последовательности упорядочены, они должны выполняться быстрее & mdash; O(n), а не то, что .Intersect() обычно есть (не помню, с моей головы). Но если вы не знаете, что они заказаны, это, скорее всего, не даст правильных результатов:

public static IEnumerable<T> OrderedIntersect<T>(this IEnumerable<T> source, IEnumerable<T> other) where T : IComparable
{
    using (var xe = source.GetEnumerator())
    using (var ye = other.GetEnumerator())
    {
        while (xe.MoveNext())
        {
           while (ye.MoveNext() && ye.Current.CompareTo(xe.Current) < 0 )
           {
              // do nothing - all we care here is that we advanced the y enumerator
           }
           if (ye.Current.Equals(xe.Current))
              yield return xe.Current;
           else
           {  // y is now > x, so get x caught up again
              while (xe.MoveNext() && xe.Current.CompareTo(ye.Current) < 0 )
              { } // again: just advance, do do anything

              if (xe.Current.Equals(ye.Current)) yield return xe.Current;
           }

        }
    }
}
2 голосов
/ 15 июля 2009

Если вы под лямбда-синтаксисом подразумеваете настоящий LINQ-запрос, он выглядит так:

IEnumerable<int> j =
   from cItem in c
   join aitem in a on cItem equals aItem
   select aItem;

Лямбда-выражение - это когда вы используете оператор =>, например:

IEnumerable<int> x = a.Select(y => y > 5);

То, что у вас есть с методом Union, на самом деле это не-LINQ способ сделать это, но я предполагаю, что вы подразумеваете способ сделать это без методов расширения. Вряд ли для этого есть одна строчка. Я сделал нечто подобное, используя словарь вчера. Вы могли бы сделать так:

Dictaionary<int, bool> match = new Dictaionary<int, bool>();
foreach (int i in c) match.Add(i, false);
foreach (int i in a) {
   if (match.ContainsKey(i)) {
      match[i] = true;
   }
}
List<int> result = new List<int>();
foreach (KeyValuePair<int,bool> pair in match) {
   if (pair.Value) result.Add(pair.Key);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...