2013-10-29 45 views
0

鑑於名單像這些成千上萬的對象列表:獲取範圍的對象,沒有空位:

var list = new List<PointAddress>(); 
list.Add(new PointAddress { Line = 1, Number = 100f }); 
list.Add(new PointAddress { Line = 1, Number = 101f }); 
list.Add(new PointAddress { Line = 1, Number = 105f }); 
list.Add(new PointAddress { Line = 1, Number = 106f }); 
list.Add(new PointAddress { Line = 2, Number = 103f }); 
list.Add(new PointAddress { Line = 2, Number = 104f }); 

什麼是創建無間隙範圍的最佳方式(基於號碼屬性)像下列? 如果Number屬性的差異大於1,那麼它是一個差距,Number應該在不同的組中。

組1

線= 1,總數= 100F
線= 1,總數= 101F

組2

線= 1,總數= 105F
線= 1,數= 106f

組3

Line = 2,Number = 103f
Line = 2,Number = 104f

基本上,如果間隙> 1,那麼它應該在Line中的不同組中。

如果該行不同,則它是不同的組。如果Number是相鄰的數字,並且Line是相同的,那麼它必須與示例中所示的組相同。第1行分爲2組 - 組1和組2,因爲Number不相鄰。

+1

爲什麼'103.0..104.1'不被視爲缺口?什麼是「差距」? – zerkms

+0

你的意思是差距是<2?所以100.0和102.0有GAP,但100.0和101.9沒有GAP? –

+0

另外兩條記錄沒有「間隙」,但是「線條」的編號不同,它們是分組在一起的嗎? @Sadek我的錢是關於兩個數字之間的差異,無論是四捨五入還是截斷,而數字大於1>都是差距,所以'100.4.102.1'應該有一個。但這只是一個猜測,直到我們獲得更多信息。 –

回答

2

假設您的清單是有序的,類似下面的內容應該可以工作。

首先,一個簡單的通用的LINQ擴展分區列表:

public static IEnumerable<List<T>> Partition<T>(this IEnumerable<T> source , Func<T,T,bool> areAdjacent) 
{ 
    List<T> list = null ; 
    T  prev = default(T) ; 

    foreach (T curr in source) 
    { 
    if (list == null) 
    { 
     list = new List<T> {curr} ; 
    } 
    else if (areAdjacent(prev,curr)) 
    { 
     list.Add(curr) ; 
    } 
    else 
    { 
     yield return list ; 
     list = new List<T> {curr} ; 
    } 

    prev = curr ; 
    } 

    if (list != null) 
    { 
    yield return list ; 
    } 

} 

然後你就可以調用它因此

List<PointAddress> addressList = GetSomeEnormousList() ; 

List<List<PointAddress>> ranges = addressList 
            .Partition((prev,curr) => curr.Line == prev.Line && curr.Number - prev.Number == 1.0) 
            .ToList() 
            ; 

所有你需要的是將採取兩種PointAddress項目和比較拉姆達他們確定是否存在序列中斷,如果兩個項目被認爲是相鄰的,則返回true或者如果它們不相同則返回false。您如何確定訂單和相鄰兩個訂單集中的項目取決於您。

如果列表是無序的,你可以訂購:

List<List<PointAddress>> ranges = addressList 
            .OrderBy(x => x.Line) 
            .ThenBy(x => x.Number) 
            .Partition((prev,curr) => curr.Line == prev.Line && curr.Number - prev.Number == 1.0) 
            .ToList() ; 

輕鬆!

+0

很酷。謝謝。我會試一試。 – user2934236

+0

工作得很好。好的解決方案 – user2934236

相關問題