我对F#很新,我遇到了F#中的"Collection was modified"问题.我知道当我们在同时修改(添加/删除)它时迭代Collection时,这个问题很常见.stackoverflow中的先前线程也指向此.
但就我而言,我正在开发两套不同的产品:我有两个系列:
以下是代码:
Seq.iter ( fun input -> ignore <| originalCollection.Remove(input)) colToRemove
Run Code Online (Sandbox Code Playgroud)
我收到以下运行时错误:+ $ exception {System.InvalidOperationException:Collection已被修改; 枚举操作可能无法执行.
System.ChrowHelper.ThrowInvalidOperationException(ExceptionResource资源)位于System.Collections.Generic.List 1.Enumerator.MoveNextRare()
at System.Collections.Generic.List1.Enumerator.MoveNext()at Microsoft.FSharp.Collections.IEnumerator.next@174 [T](FSharpFunc 2 f, IEnumerator1 e,FSharpRef 1 started, Unit unitVar0)
at Microsoft.FSharp.Collections.IEnumerator.filter@169.System-Collections-IEnumerator-MoveNext()
at Microsoft.FSharp.Collections.SeqModule.Iterate[T](FSharpFunc2 action,IEnumerable `1来源)
这是代码块:
match newCollection with
| Some(newCollection) ->
// compare newCollection to originalCollection.
// If there are things that exist in the originalCollection that are not in the newCollection, we want to remove them
let colToRemove = Seq.filter (fun input -> Seq.exists (fun i -> i.id = input.id) newCollection) originalCollection
Seq.iter ( fun input -> ignore <| originalCollection.Remove(input)) colToRemove
| None -> ()
Run Code Online (Sandbox Code Playgroud)
谢谢!
注意:在此处处理单线程环境,因此不存在可能导致此异常的多线程问题.
这里的问题是,colToRemove它不是一个独立的集合,而是一个集合的投影originalCollection.因此,更改会originalCollection更改迭代期间不允许的投影.上述代码的C#等价物如下
var colToRemove = originalCollection
.Where(input -> newCollection.Any(i -> i.id == input.id));
foreach (var in input in colToRemove) {
originalCollection.Remove(input);
}
Run Code Online (Sandbox Code Playgroud)
您可以colToRemove通过该List.ofSeq方法进行独立收集来解决此问题.
let colToRemove =
originalCollection
|> Seq.filter (fun input -> Seq.exists (fun i -> i.id = input.id) newCollection) originalCollection
|> List.ofSeq
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
273 次 |
| 最近记录: |