2013-06-05 113 views
2

我在C#中的對象,它有幾個特性:獲取從集合對象使用LINQ

// Pseudo class 
public class 
{ 
    Id; 
    To; 
    From; 
} 

我有一個Collection該類的實例很多。這看起來是這樣的:

object 1: 
    Id: 1 
    To: "PathA" 
    From: "PathB" 

object 2: 
    Id: 2 
    To: "PathB" 
    From: "PathC" 

object 3: 
    Id: 3 
    To: "PathC" 
    From: "PathA" 

現在我想做的是讓所有的物品,其中的To值沒有出現在任何物體的From集合。這將導致以下:

object 1: 
    Id: 1 
    To: "PathA" 
    From: "PathB" 

object 2: 
    Id: 2 
    To: "PathB" 
    From: "PathC" 

因爲與Id: 3的最後一個對象在From屬性,它已經在某處To屬性存在有PathA

我該如何用Linq查詢做到這一點?

回答

2

那麼,怎麼去解決這個問題呢?首先,您可以創建To所有值的索引。然後,篩選基礎上,From財產的順序...

喜歡的東西:

var tos = new HashSet<string>(collection.Select(item => item.To)); 
var filtered = collection.Where(item => !tos.Contains(item.From)); 

你可能要檢查,如果創建一個HashSet真的是這樣的,或者如果你需要以不同的方式構建它...但你明白了。集是有效的,如果tos變得比較長,因爲你會被檢查這個有很多...

+0

'真的像這樣工作' - 它確實,'HashSet'構造函數之一需要'IEnumerable ',因爲Linq'Select'返回'IEnumerable '這會編譯和工作。我也喜歡MoreLINQ'ToHashSet()'擴展方法,你不需要聲明''泛型參數,都是推斷出來的。 –

+0

@IlyaIvanov :)不錯。我喜歡它,當一個框架按預期工作時! –

0
var list = collection.Select(c=>c.To).Distinct().ToList(); 
var result = collection.Where(c=>!list.Contains(c.From)).ToList(); 
1

說你的對象的集合如下:

var objects = { object1, object2, object3 } 

然後你想:

var result = objects.Where(o => !objects.Select(x => x.From).Contains(o.To)); 

如果涉及大型數據集,它可能是智能緩存和存儲的子選擇「從」路徑:

var fromPaths = new HashSet<string>(objects.Select(x => x.From)); 
var result = objects.Where(o => !fromPaths.Contains(o.To)) 
0

如果您使用收件人和發件人爲各自的鍵加入收藏回到其自身上,你可以建立哪些項目是「加盟」通過到/從和排除它們:

var itemsThatAreConnected = 
    collection.Join(collection, x => x.To, x => x.From, (a,b) => a); 
var unconnected = collection.Except(itemsThatAreConnected); 
1

首先,您的樣本並不真正匹配問題文本,因爲所有示例對象都有一個To對應於其他一些From。不過,假設的問題,文本是正確的,樣本是錯誤的:

如何用group-join

var query = from obj in collection 
      join fromObj in collection 
       on obj.To equals fromObj.From 
       into objGroup 
      where !objGroup.Any() 
      select obj; 

另外,建立了一套獨特的第一櫨:

var distinctFroms = new HashSet<string>(collection.Select(item => item.From)); 

var query = from obj in collection 
      where !distinctFroms.Contains(obj.To) 
      select obj;