2009-09-11 13 views
11

我有一些代碼想將其轉換爲linq表達式(最好使用lambda表達式),以使它更容易用作委託。代碼看起來像這樣:Linq表達式將數組的所有值設置爲給定值

List<DateTime[]> changes = new List<DateTime[]>(); 
changes = PopulateChanges(); 
for (int i = 0; i < changes.Count; i++) 
{ 
    for(int j = 0; j < changes[i].Length; j++) 
    { 
     changes[i][j] = DateTime.MinValue; 
    } 
} 

對於我的生活,我似乎無法找出這一個。我已經嘗試使用ForEach和各種形式的選擇等。沒有什麼似乎工作正確。我知道DateTime默認爲MinValue,實際上這是在數組已經被設置之後將數組清除爲默認數組。

任何人都可以幫我一個工作表達?

編輯:

我想我真正要說這裏是我想要一個簡潔的方式,以多維數組的所有元素設置爲給定值。當然,嵌套for循環的作品,我當然可以把它放在一個函數中(我已經完成了)。我只想要更簡潔的東西,可以更容易地在代表中使用,而不會創建多行怪物。

回答

14

這應該可以做到。

這不是LINQ,它和嵌套的for循環並沒有太大的不同,只是略少一些。 (ab)使用LINQ獲得相同的結果肯定有方法,但我認爲它們是骯髒的黑客。此外,LINQ等價物可能不會比我上面的示例更加冗長。

+0

我喜歡這個。我想,足夠接近我。 – 2009-09-11 22:56:06

2

LINQ並非真正用於更新集合。 這涉及查詢,即在現有集合上創建枚舉類型。 我認爲你的代碼是完全可讀的,如果你強迫它有很多lambda表達式等,它們不會有太大的改進。

如果你想創建一個新的List<DateTime[]>設置爲一個值的每個元素,你可以這樣做:

var changes = Enumerable.Range(0, width) 
         .Select(x => Enumerable.Range(0, height) 
               .Select(y => DateTime.MinValue) 
               .ToArray()) 
         .ToList(); 

如果你真的希望它使用ForEach/LINQ做的,有可能被濫用Select(但我不建議這樣做):

changes.ForEach(array => array.Select((dt, i) => array[i] = DateTime.Now) 
           .LastOrDefault()); 
+0

我真的不明白你爲什麼說這不是爲了這個。考慮一下查詢數據然後更新值的典型Linq2SQL查詢。這有什麼不同? – 2009-09-11 21:50:22

+3

用LINQ2SQL查詢數據庫,然後修改返回的對象。如果你想修改所有返回的對象,你仍然需要使用循環遍歷對象。包含對象的枚舉根本不被修改。 LINQ是關於查詢,而不是更新集合。 – dtb 2009-09-11 21:59:59

2

一個有趣的問題,但LINQ的約查詢,你在這裏做什麼看起來不像對我的查詢。即使有解決方案,我不確定我會使用Linq來做這樣的事情。

+1

我不同意,它實際上是一個查詢,但帶有副作用的查詢。我正在查詢返回列表的每個元素,因此我可以設置這些值。在Linq中有很多這樣的查詢,比如預測轉換等。我真的不知道這有什麼不同。 – 2009-09-11 21:48:46

+4

在LINQ中沒有任何修改查詢集合的查詢(因此「查詢」)。 – dtb 2009-09-11 22:02:28

+0

沒有什麼修改原來的,但我認爲他正在努力完成的任務...... – bytebender 2009-09-11 22:04:56

0

你能描述一些你建議如何使用這個委託的用例嗎?

我的意思是,如果PopulateChanges()返回一個DateTime數組的List <>,並且您正在檢查所有這些數組並將它們設置爲DateTime.MinValue,那麼您希望將代碼單元放到什麼位置代表?

+0

我所做的就是創建一個工作示例,正如我的供求信息所述......我真的只是在與其不同的區域調整for循環部分(其餘部分只是設置)。我有另一個列表包含數據,這只是將字符串數組的每個元素映射到他們上次更改的時間。當更改被清除時,我需要將時間重置爲MinValue。當新的更改發生時,那些元素將獲得新的DateTime。 – 2009-09-11 21:44:49

0

總有一些最佳實踐等,但我不知道我的一切,每個人都已經表示同意...

如果我理解正確的話,你必須列舉你的嵌套數組幾個不同的原因和想封裝這個功能可以重複使用。有幾種不同的方式來實現,但這裏是一個使用LINQ和一個用了...

List<DateTime[]> changes = new List<DateTime[]>(); 
changes = PopulateChanges(); 

// *** As pointed out ForEach this will not change the value in the array, Thanks!*** 
changes.ForEach(change => change.ToList().ForEach(date => date = DateTime.MinValue)); 

// this how ever works but is kind of confusing... 
changes = changes.Select(change => change.Select(date => DateTime.MinValue).ToArray()).ToList(); 
//Even that would get old writing it over and over again... 

我會做這樣......

private void ForEachOnNestedDates(List<DateTime[]> list, Func<DateTime, DateTime> method) 
{ 
    // Use your code... 
    for (int i = 0; i < list.Count; i++) 
    { 
     for(int j = 0; j < list[i].Length; j++) 
     { 
      list[i][j] = method.Invoke(list[i][j]); 
     } 
    } 
} 

這將允許您重複使用並對每個項目執行不同的操作。恩。

//Add a Day to each datetime value 
ForEachOnNestedDates(changes, (DateTime date) => date.AddDays(1)); 

//You also make it even more readable 
ForEachOnNextedDates(changes, DoSomethingWithDate); 

private DateTime DoSomethingWithDate(DateTime value) 
{ 

} 

這將用於完成每個日期時間的事情,而不是每個日期時間完成的事情......這將有所不同。

+2

爲拉姆達的參數賦值並不會改變查詢的集合... – dtb 2009-09-11 21:33:45

+0

我站好了。第二個選項應該可以... – bytebender 2009-09-11 21:39:57

相關問題