F# dictionary entry grouping and sort issue
-
Saturday, March 02, 2013 6:54 PM
Hello,
let dNum = new Dictionary<int, decimal>()
dNum.Add(0, 0M)
dNum.Add(1, 10M)
dNum.Add(2, 20M)
dNum.Add(3, 30M)
dNum.Add(4, 40M)
dNum.Add(5, 30M)
dNum.Add(6, 20M)
I want to do this:
Let’s divide the dictionary entries into groups of 3 consecutive entries, and check to see if the 3 entries are in ascending order or descending order, and if in ascending order, and if the first entry is less than the last entry by 10+, then create a new dictionary and add the entry as +1; and if in descending order, and if the first entry is more than the last entry by 10+, then create a new dictionary and add the entry as -1, otherwise, create a new dictionary and add the entry as 0.
For example: in the above example: dNum entries: (1, 10M); (2, 20M); (3, 30M), then new dictionary:
dNumSort.Add(1, 1)
The final result for my example will be like this:
let dNumSort = new Dictionary<int, int>()
dNumSort.Add(0, 1)
dNumSort.Add(1, 1)
dNumSort.Add(2, 1)
dNumSort.Add(3, 0)
dNumSort.Add(4, -1)
I think I can do this using non-functional way, but can’t figure out the functional way.
To divide the dictionary entries into groups of 3 consecutive entries, I can use the following:
let group3 = dNum
|> Seq.map (fun (KeyValue(k,v)) -> v)
|> Seq.windowed 3
However, how to check to see if the group is in ascending or descending order and others seem not easy to put together.
Any idea is welcome!
All Replies
-
Sunday, March 03, 2013 12:23 AM
It's a little ugly (not really overthought the thing) but seems correct
open System.Collections.Generic let dNum = Dictionary (dict [ 0, 0M; 1, 10M; 2, 20M; 3, 30M; 4, 40M; 5, 30M; 6, 20M ]) let result = Dictionary ( dNum |> Seq.map (|KeyValue|) |> Seq.windowed 3 |> Seq.map (fun arr -> let (k, v1), (_, v2), (_, v3) = arr.[0], arr.[1], arr.[2] // alternative for previous line but give a warning for incomplete match // but we know for sure the array has only 3 items //|> Seq.map (fun [| k, v1; _, v2; _, v3 |] -> k, if abs (v1 - v3) >= 10M then if v1 <= v2 && v2 <= v3 then 1 elif v1 >= v2 && v2 >= v3 then -1 else 0 else 0) |> dict)
Forgive my writing, English isn't my native language.
- Marked As Answer by zydjohn Saturday, March 09, 2013 8:46 AM
-
Saturday, March 09, 2013 8:47 AM
Thank you very much!
Your code works!
Thanks and have a nice weekend.
John