代码之家  ›  专栏  ›  技术社区  ›  Curtis White

包含的Linq自定义比较器?

  •  2
  • Curtis White  · 技术社区  · 14 年前

    我有两张单子。我想使用linq(而不是使用嵌套循环)将两个列表中的每个元素与每个元素进行比较。但是,包含不满足我的需要,因为我需要进行自定义比较。我可以想象自定义比较器是我需要的,但不是100%确定。

    我认为这不应该太难,但不确定我需要什么样的工具。这两个列表都包含不同类型的对象。

    更新:

    对不起,如果我不清楚的话。我有两个列表(或可枚举列表),我可以这样做:

    foreach(item i in list1)
      foreach(otherItemType in List2)
      {
        if ( CompareItem(x) ) do something;
      }
    

    我想做的是这样的事情:

    var matches = myList1.Where(t => myList2.Something(t) ) 
    

    什么是自定义比较器,也许我可以覆盖等号比较?我可以使用 .Contains 但我需要做我自己的逻辑比较。

    更新: 我想用 IEqualityComparer 但这是以T、T和T、Y的类型设置的,可能有一些通用约束,我可以用它们来解决这个问题。我觉得这应该很简单。

    4 回复  |  直到 14 年前
        1
  •  2
  •   strager    14 年前
    var matches = myList1.SelectMany(
        t1 => myList2.Where(
            t2 => t2.Something(t1)
        )
    );
    

    内部 Where 就像你的内心 foreach 循环,以及外部 SelectMany 像在外部一样通过迭代后联接结果 前额 循环。

    您还可以创建一个函数来执行此操作(未测试;无法调用扩展语法):

    public static IEnumerable<T2> MultiCompare<T1, T2>(this IEnumerable<T1> first, IEnumerable<T2> second, Func<bool, T1, T2> comparer) {
        return first.SelectMany(
            t1 => second.Where(
                t2 => comparer(t1, t2)
            )
        );
    }
    
        2
  •  1
  •   Rob    14 年前

    如果我能正确理解你的问题,下面的例子就可以了。自从 任何 接受委托您可以定义列表中两个元素之间的任意匹配比较。如果需要所有元素匹配,请使用 所有 代替 任何 .

    [Test]
    public void StackOverflow()
    {
      var digits = new int[] {1, 2, 4, 9};
      var strings = new string[] {"1", "4", "5", "7"};
    
      var matches = strings.Where(s => digits.Any(d => d.ToString() == s)).ToList();
    
      // Prints
      // 1
      // 4
    
      matches.ForEach(x => System.Diagnostics.Debug.WriteLine(x));
    }
    
        3
  •  1
  •   theburningmonk    14 年前

    如何使用 Enumerable.Join ?

    var list = new List<int> { 1, 2, 3, 4, 5 };
    var list2 = new List<string> { "2", "4", "5" };
    
    var matches = from i in list
                  join s in list2 on i.ToString() equals s
                  select i; // if you want to use the matching items from the 1st list
    
    // there's no ForEach on Enumerable so you'd have to write the extension yourself (which is easy)
    // or you could just output matches to a List first
    matches.ToList().ForEach(i => Console.WriteLine(i));
    

    在连接方面,我非常喜欢LINQ查询语法,尽管您可以同样使用lambda表达式,但它们通常看起来有点混乱…

        4
  •  0
  •   Community CDub    8 年前

    我有问题 here 一段时间前,这可能会帮助你开始。