2011-05-29 14 views
2

我想提取IEnumerable序列的所有項,其鍵值等於另一個IEnumerable序列中的某個鍵值。 請考慮第一序列類型 'T' 的,其中T是:IEnumerable <T>的提取項,其鍵值等於IEnumerable中的一個KeyValues <U>

class T 
{ 
    int SpecificValue; 
    // other payload 
} 

和第二序列的類型爲 'U',其中U是:

class U 
{ 
    int SpecificValueOfSameType; 
    // other payload (different from class T) 
} 

這可能嗎?

作爲一個邊節點:我使用了術語「Key」 - 值,但不能保證這個值在兩個序列中都是唯一的。它應該有助於更詳細地解釋我的要求。在真實代碼中,我可以想象有某種比較函數參數)。

回答

1

試試這個:

Ts.Where(t => Us.Select(u => u.SpecificValueOfSameType).Contains(t.SpecificValue)) 
+0

這就是我已經得到的。認爲有些事情是直截了當的。 (順便說一句,我想你想寫「.Contains(t.SpecificValue)」。所以,「t」,而不是「y」)。 – 0xbadf00d 2011-05-29 13:50:55

+0

另一種方法是使用連接,但如果我只需要從一個集合中選擇項目,我嘗試避免連接;固定「t」thx – 2011-05-29 14:01:12

3

這聽起來像你正在尋找一個Join

ts.Join(us, t => t.SpecificValue, u => u.SpecificValueOfSameType, (t, u) => new Something) 
+0

不,我不想合併/ ZIP這兩個集合。我只是想根據與另一個集合有關的條件從一個集合中提取值。 – 0xbadf00d 2011-05-29 13:52:22

+0

這樣的連接不會引入重複嗎? {1,1,2,2}與{1,1,2,2,2,2} = 12結果相匹配。應該是4個結果。 – 2011-05-29 19:18:51

1

爲K·伊萬諾夫曾表示,你可以使用Contains - 但如果你的收藏是相當大的,你最好離他們將在一個HashSet第一:

var keys = new HashSet<T>(us.Select(u => u.SpecificValueOfSameType)); 
var query = ts.Where(t => keys.Contains(t.SpecificValue)); 

編輯:我錯過了可能在任何集合中都有重複鍵的事實。對於上面的代碼來說沒問題,但對於一個連接來說並不合適(至少不是沒有Distinct的調用)。

這並不完全清楚你的意思是「Compare-Func」參數。如果這只是從序列中提取密鑰的方式,那很好。如果它是一個比較兩個鍵相等的函數,那就是另一回事了。這將意味着你不可能意味着哈希。

0

不能保證這個值在兩個序列中都是唯一的。

那麼,這表明你想遠離大多數加入。

GroupJoin怎麼樣?當有多個匹配時,這種連接類型不會引起重複。

from t in tSource 
join u in uSource 
    on t.SpecificValue 
    equals u.SpecificValueOfSameType 
    into g 
where g.Any() 
select t; 

也可以寫成:

tSource.GroupJoin(uSource, 
    t => t.SpecificValue, 
    u => u.SpecificValueOfSameType, 
    (t, g) => new {t, g}) 
.Where(x => x.g.Any()) 
.Select(x => x.t) 
+0

所以,當它「不會引入重複」時,它會導致不同的值?那不是我所追求的。該值不是唯一的,但這並不意味着具有相同值的兩個記錄表示相同的實體。 – 0xbadf00d 2011-05-30 06:33:57

相關問題