What you describe is a map data-structure, so i would use one, instead of implementing it yourself with a bunch of list functions you can convert your two lists in such a way
let k = [1;1;2;2;3;3]
let n = [1;2;3;4;5;6]
let mapKeyToValues keys values =
let folder m k v =
m |> Map.change k (function
| Some old -> Some (v :: old)
| None -> Some [v]
)
List.fold2 folder Map.empty keys values
Now with
let r = mapKeyToValues k n
You get a data-structur like
Map [
1, [2; 1]
2, [4; 3]
3, [6; 5]
]
This would be equivalent to the JSON-Object
{
"1": [2,1],
"2": [4,3],
"3": [6,5]
}
Usually you could write
let r = Map (List.zip k n)
This way, out of a tuple with (k,v) you create such a map-datastructure. But a new key, just ovverrides an older, so you get
Map [
(1, 2)
(2, 4)
(3, 6)
]
That's the reason why you need Map.change. You go through every (key,value) of a list with List.fold2 and then add it to the map data-structure. If a key is not present (the None case) you create a list as a value with your only value. In the Some case a key was already added, and you add your value to the list that is already present.
In this example i suppose the order of the values doesn't matter. If you want the same order as they appear in the value list, you must use List.foldBack2 instead of List.fold2. But you must change the order of some arguments. This should be an exercise for you, to understand it better.
There is a Map module with different functions to work with such a data-structure, and it also provides things like Map.map, Map.filter, Map.fold, Map.find, ... and so on. So use this instead. If really needed you also could use Map.toList to transform it back to a list again, or use Map.fold.
Anyway as a reminder, as some people use (List.zip and then List.map) or (List.zip and then List.fold). There is a List.map2 and List.fold2 that does this in one operation instead of two.