C# - 查找两个 List的公共成员 - Lambda 语法

发布于 2024-07-27 12:26:19 字数 513 浏览 5 评论 0原文

因此,我编写了这个简单的控制台应用程序来帮助我提问。 在方法的第 3 行使用 lambda 表达式来获取公共成员的正确方法是什么。 尝试了 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());

    }
}

So I wrote this simple console app to aid in my question asking. What is the proper way to use a lambda expression on line 3 of the method to get the common members. Tried a Join() but couldn't figure out the correct syntax. As follow up... is there a non-LINQ way to do this in one line that I missed?

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

    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撑一把青伞 2024-08-03 12:26:19

您需要 Intersect()

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

这是一个基于评论中提到的想法的 OrderedIntersect() 示例。 如果你知道你的序列是有序的,它应该运行得更快 - 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;
           }

        }
    }
}

You want Intersect():

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

Here's an OrderedIntersect() example based on the ideas mentioned in the comments. If you know your sequences are ordered it should run faster — O(n) rather than whatever .Intersect() normally is (don't remember off the top of my head). But if you don't know they are ordered, it likely won't return correct results at all:

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

        }
    }
}
桜花祭 2024-08-03 12:26:19

如果您所说的 lambda 语法是指真正的 LINQ 查询,那么它看起来像这样:

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

lambda 表达式是指当您使用 => 时。 运算符,例如:

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

If you by lambda syntax mean a real LINQ query, it looks like this:

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

A lambda expression is when you use the => operator, like in:

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

What you have with the Union method really is a non-LINQ way of doing it, but I suppose that you mean a way of doing it without extension methods. There is hardly a one-liner for that. I did something similar using a Dictionary yesterday. You could do like this:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文