0

不完全确定如何最好地表达这个问题。如何仅将列表的每个元素与同一列表的每个元素进行一次比较。

例如:

var textlist = ["a", "b", "c"];
var intersecting = from string a in textlist
                   from string b in textlist
                   where a != b && a.SomeCondition(b)
                   select new
                   {
                       object1 = a,
                       object2 = b
                   };

假设“a”用“b”为“SomeCondition”提供“True”,我希望最终结果是:

[["a, b"]]

而现在它将是:

[["a, b"], ["b, a"]]

这可能与 Linq 查询吗?

4

4 回答 4

2

您可以使用值比较 - 即只处理 a > b 的对。你甚至可以用 替换你a != ba > b,因为不等式将被暗示:

var textlist = ["a", "b", "c"];
var intersecting = from string a in textlist
               from string b in textlist
               where a > b && (a.SomeCondition(b) || b.SomeCondition(a))
               select new
               {
                   object1 = a,
                   object2 = b
               };
于 2012-08-06T01:56:24.830 回答
1

我通过添加CompareTo条件得到了您想要的结果:

string[] textlist = new string[] {"a", "b", "c"};
var intersecting =  from string a in textlist
                    from string b in textlist
                    where ((a != b) && (a.CompareTo(b) == -1)) // && a.SomeCondition(b)
                    select new { object1 = a, object2 = b }
                    ;

intersecting.Dump("Result");

这是结果的屏幕截图

在此处输入图像描述

您可以删除多余的内容//以取消注释您的条件。

于 2012-08-06T02:27:59.873 回答
1

一种方法是将每个元素与位于它之后的元素进行比较:

string[] textlist = {"a", "b", "c"};
var intersecting = from aIndex in Enumerable.Range(0, textlist.Count())
                   from b in textlist.Skip(aIndex + 1)
                   let a = textlist.ElementAt(aIndex)
                   where a != b && a.SomeCondition(b)
                   select new
                   {
                       object1 = a,
                       object2 = b
                   };

注意:如果在枚举成本很高的 IEnumerable 上使用此解决方案以及使用 LINQ 解决此问题的大多数解决方案,效率将非常低。

于 2012-08-06T03:19:48.157 回答
0

这是另一种方法,以防您无法在对象之间使用 > 或者您的集合可能包含重复项。它通过使用 SelectMany 和 Where 的重载来工作,该重载将索引传递给集合中的项目。我意识到它不是那么可读,但我认为它更健壮。

        string[] data = "A,A,B,C".Split(',');
        var query = data.SelectMany((x1, i1) => data.Where((x2, i2) => i2 > i1 && x1.SomeCondition(x2)).Select(x2 => new { object1 = x1, object2 = x2 }));
        foreach (var item in query) Console.WriteLine(item.object1 + "," + item.object2);
于 2012-08-06T03:38:18.723 回答