2012-08-06 64 views
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 
        }; 

假設 「一個」 讓 '真' 到 「SomeCondition」 與 「B」,我想最後的結果是:

[["a, b"]] 

而現在它會是:

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

這是可能的一個Linq查詢?

+0

如果您的輸入是{「a」,「a」,「b」,「c」},您會期望什麼? – 2012-08-06 01:55:42

+0

我以爲只有當字符串列表是'a,b,c'時,你纔想比較'{[a,b],[a,c],[b,c]}'? – 2012-08-06 03:15:05

回答

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

注意:此方法,與大多數解決這個問題,使用LINQ一起,如果上的使用將是可怕的低效IEnumerable枚舉昂貴。

+0

不是100%確定您有「最佳(tm)」解決方案,但它是_exactly_我​​正在尋找的。其他人不工作,除非我做了比較操作符,所以我將其標記爲已回答。 – HotStuff68 2012-08-07 02:41:02

+0

@HotStuff我很高興這是你想要的!我相信對於急切評估的集合來說,這是一個非常有效的解決方案,因爲與比較解決方案不同,它將每個元素與其他元素的一部分進行比較。另外,如果'where a!= b'只是爲了防止將一個元素與自身進行比較,則不需要它,因爲'b'將始終是'a'之後的元素。如果你希望這個解決方案對延遲評估的集合有效,你可以在使用它們之前將它們轉換爲渴望的集合。 – 2012-08-07 14:27:40

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

我已經拿出你期望的結果加上CompareTo condtion:

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

這裏的結果的截圖

enter image description here

你可以刪除多餘的//取消註釋你的狀況。

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); 
相關問題