2010-10-10 27 views
2
var tmpProjection = myCollection.ToLookup(t => t.SomeBoolValue); 
var listOneFinal = tmpProjection[true]; 
var listTwo = tmpProjection[false]; 

第一個問題,有沒有將其分配到那麼listOne和listTwo以某種方式更短的方式,我知道我是迂腐這裏,...只是問。LINQ中,使用ToLookup項目值,以不同的命名變量

現在,

var listThree = listTwo.ToLookup(t => t.SomeOtherBoolValue); 
var listFourFinal = listThree[false]; 
var listFiveFinal = listThree[true]; 
在thise情況下

所以,我只需要(最終)listOneFinal,listFourFinal和listFiveFinal - 但我創造......這間臨時的東西是有減少的方式這個。

我只說代碼方面不是性能或代碼的關鍵性。

回答

0

我認爲你已經有了相當不錯的說法,說實話。

如果你只是希望儘量減少聲明數,我懷疑你可以做得比:

var listOneFinal = myCollection.Where(t => t.SomeBoolValue); 
var listFourFinal = myCollection.Where(t => !t.SomeBoolValue && !t.SomeOtherBoolValue); 
var listFiveFinal = myCollection.Where(t => !t.SomeBoolValue && t.SomeOtherBoolValue); 

或許:

var predicates = new Func<MyClass,bool>[]{ t => t.SomeBoolValue, t => t.SomeOtherBoolValue}; 
var listOneFinal = myCollection.Where(predicates.First()); 
var listFourFinal = myCollection.Where(t => !predicates.Any(p => p(t))); 
var listFiveFinal = myCollection.Where(t => !predicates[0](t) && predicates[1](t)); 

(對每個查詢電話ToList()如果需要的話)

但是真的,我更喜歡你的技術要好得多,我提供的代碼不是parti更具可讀性高效。

您可能需要考慮只存儲2個查找,而不是每個列表,並在必要時內聯每個'最終查找',因爲調用Lookup[key]很便宜。所以,只要您需要listFourFinal,只需撥打listThree[false].顯然,更好的變量名稱將有所幫助。

1

你可以用更少的語句來完成它,但是因爲你需要結束3個值,所以你至少需要3個賦值。你的代碼是非常可讀的,不要犧牲「聰明」的可讀性和減少語句。這就是說,這是一個3聲明的版本;這將很好地工作,如果集合小(自己的版本將有較大的收藏有更好的表現,因爲這個版本遍歷集合多次):

var listOneFinal = myCollection.Where(t => t.SomeBoolValue); 
var listFourFinal = myCollection.Where(t => !t.SomeBoolValue && !t.SomeOtherBoolValue); 
var listFiveFinal = myCollection.Where(t => !t.SomeBoolValue && t.SomeOtherBoolValue); 

根據您的實際使用情況,上面可能更可讀。

3

bool對於溝通意圖很弱。 Int更好一些,枚舉最好。

Lookup<int, T> myLookup = myCollection 
.ToLookup(t => 
    t.someBoolValue ? 1 : 
    t.someOtherBoolValue ? 4 : 
    5 
); 

var listOne = myLookup[1]; 
var listFour = myLookup[4]; 
var listFive = myLookup[5]; 
+0

+1:輝煌,完全錯過了這個想法! – Ani 2010-10-10 15:20:41

0

如果你發現自己經常這樣做,你可以寫一個函數來做到這一點。對於布爾型ToLookup,我們可以使用C#的out parameters返回多個值。

public static void Dichotomize<T>(this IEnumerable<T> source, 
            Func<T,bool> keySelector, 
            out IEnumerable<T> affirmative, 
            out IEnumerable<T> negative) { 
    if (source == null) throw new ArgumentNullException("source"); 
    if (keySelector == null) throw new ArgumentNullException("keySelector"); 

    var affirmativeList = new List<T>(); 
    var negativeList = new List<T>(); 
    foreach (var element in source) { 
     (keySelector(element) ? affirmativeList : negativeList).Add(element); 
    } 
    affirmative = affirmativeList.AsReadOnly(); 
    negative = negativeList.AsReadOnly(); 
} 

現在我們可以這樣做:

IEnumerable<T> listOneFinal, listTwo, listFourFinal, listFiveFinal; 
myCollection.Dichotomize(t => t.SomeBoolValue, out listOneFinal, out listTwo); 
listTwo.Dichotomize(t => t.SomeOtherBoolValue, out listFiveFinal, out listFourFinal); 
相關問題