list - F# System.InvalidOperationException: Collection was modified; enumeration operation may not execute -
i encountering problem in f# [not c# there similar post similar answer]
i understand not possible modify dictionary while enumerating in loop how should go around ?
let edgelist1 = [(1,2,3.0f);(1,2,4.0f);(5,6,7.0f);(5,6,8.0f)] let dict_edges = new dictionary<int*int,(int*int*float32) list>() x in edgelist1 dict_edges.add ((fun (a,b,c)-> (a,b)) x, x) k in dict_edges.keys dict_edges.[k] <- (dict_edges.[k] |> list.rev)
system.invalidoperationexception: collection modified; enumeration operation may not execute.
at system.throwhelper.throwinvalidoperationexception(exceptionresource resource) @ system.collections.generic.dictionary`2.keycollection.enumerator.movenext() @ .$fsi_0101.main@()
individually working
dict_edges.[(1,2)] <- dict_edges.[(1,2)] |> list.rev;;
in loop need change dictionary values, not keys.
thanks
the code posted not syntactically correct, it's not clear precisely trying achieve (compiler screams @ ((fun (a,b,c)-> (a,b)) x, x)
saying expects second x
list)
i guess after is: have list of weighted edges, there can multiple edges between nodes. you'd collapse them canonical form, have edges grouped connect pair of nodes (i,j)
. use of groupby
library functions, , you're good:
let map_edges = edgelist1 |> list.groupby (fun (a, b, _) -> (a, b)) |> map.oflist
in current code using ((fun (a,b,c)-> (a,b)) x, x)
extract members of tuple. instead, use patterns right in for
expression:
for (a, b, c) in edgelist1 dict_edges.add ((a, b), [(a, b, c)])
(i've added []
make @ least compile)
note duplicating information: store node tuple in keys , in values of list, making data structure possibly inconsistent , larger. consider following:
let map_edges = edgelist1 |> list.map (fun (a, b, c) -> (a, b), c) |> list.groupby fst |> list.map (fun (nodetuple, edgelist) -> nodetuple, (edgelist |> list.map snd)) |> map.oflist map_edges |> map.iter (fun (nodei, nodej) edgelist -> edgelist |> seq.map string |> string.concat "; " |> printfn "nodes (%i, %i): weights %s" nodei nodej )
(you may want use sequences intermediate representation rather list)
Comments
Post a Comment