2015-11-23 27 views
0

所以我对F#有点新,但是我有一个C#的背景。我正在写遍历整个Dictionary<string, int>,加1到每一个元素和元素如果该值超过100这添加到列表中的代码是我的代码:无法更改For循环中的字典值?

//Early on in the code 
let variables = new Dictionary<string, int>() 
let variablecnt = new Dictionary<string, int>() 
let trash = new List<int>() 

//Later on in the code at a higher encapsulation level 
    for KeyValue(j, k) in variablecnt do 
     variablecnt.[j] <- k+1 
     if variablecnt.[j]=100 then 
      trash.Add(0) 
      variables.Remove(j) |> ignore 

在运行此,我得到但以下情况除外:

System.InvalidOperationException was unhandled 
Message: An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll 
Additional information: Collection was modified; enumeration operation may not execute. 

行号它给对应于:

variablecnt.[j] <- k+1 

我明白它的说法,但我怎么能做到什么,我试图做的?我花了很多时间试图弄清楚并研究一个答案,但我没有发现任何有用的东西(F#没有像C#这样的语言拥有尽可能多的资源)。我已经尝试将mutable关键字添加到let声明中,但这不会改变任何内容。

此外,我使用System.Collections.Generic.Dictionary>字典而不是F#dict(),因为我想我更熟悉.NET类。相同的原因我经常使用Console.WriteLine代替printf(对不起!)

+4

这与F#无关。在任何.NET语言中迭代它时,您都不能对集合进行变异。 – ildjarn

+0

啊...我不知道我在C#中从来没有遇到类似这样的错误。我不太经常使用字典(我经常使用数组和列表)。 – ThePhillipParadox

回答

2

也许你应该尝试这样的事情。

我故意要避开标准的.NET容器和可变的添加/删除,而是给你一个F#样式的解决方案来演示语法(我认为当你是新手时最好避免掉到熟悉的东西上) 。

// initial variable count 
let variablecnt = dict <| Seq.empty<string*int> 

/// Convert from KeyValuePair to tuple of (k*v) 
let keyVal = 
    function 
    |KeyValue(k, v) -> (k, v+1) 

// split dictionary into twp lists containing values which are 
// less than or greater than or equal to 100 respectively 
let splitAt100 = 
    Seq.map (keyVal) // map to KeyValuePairs 
    >> Seq.toList // convert to list 
    >> List.partition (fun (k,v) -> v < 100) // split into tuples based on v < 100 

// apply the splitat100 function to the variable count 
let lThan100, grEq100 = splitAt100 variablecnt 
// variables is a dictionary of the key value pairs, where the values are less than 100 
let variables = lThan100 |> dict 
// trash is a list of 0s equal in length to the number of key value pairs with 100+ values 
let trash = grEq100 |> List.map (fun _ -> 0) 

如果你想有一个可变variables场那么你可以随时用这个新一旦它已经产生更新原始。