Here is a version that resembles your version, with all the mutability removed:
(这是一个与您的版本相似的版本,其中删除了所有可变性:)
let getQueueTime (customerArray: int list) n =
let updateWith f key map =
let v = Map.find key map
map |> Map.add key (f v)
let initialLines = [1..n] |> List.map (fun i -> sprintf "Line%d" i, 0) |> Map.ofList
let getNextAvailableSupermarketLineName(d:Map<string,int>) =
let lowestLine = d |> Seq.minBy (fun l -> l.Value)
lowestLine.Key
let lines =
customerArray
|> List.fold (fun linesState x ->
let lineName = getNextAvailableSupermarketLineName linesState
linesState |> updateWith (fun l -> l + x) lineName) initialLines
lines |> Seq.map (fun l -> l.Value) |> Seq.max
getQueueTime [5;3;4] 1 |> printfn "%i"
Those loops with mutable "outer state" can be swapped for either recursive functions or folds
/ reduce
, here I suspect recursive functions would be nicer.
(那些具有可变“外部状态”的循环可以交换为递归函数或folds
/ reduce
,这里我怀疑递归函数会更好。)
I've swapped out Dictionary
for the immutable Map
, but it feels like more trouble than it's worth here.
(我已将Dictionary
换成不可变的Map
,但感觉麻烦多于这里的价值。)
Update - here is a compromise solution I think reads well:
(更新 -这是我认为很好的折衷解决方案:)
let getQueueTime (customerArray: int list) n =
let d = [1..n] |> List.map (fun i -> sprintf "Line%d" i, 0) |> dict
let getNextAvailableSupermarketLineName(d:IDictionary<string,int>) =
let lowestLine = d |> Seq.minBy (fun l -> l.Value)
lowestLine.Key
customerArray
|> List.iter (fun x ->
let lineName = getNextAvailableSupermarketLineName d
d.Item(lineName) <- d.Item(lineName) + 1)
d.Values |> Seq.max
getQueueTime [5;3;4] 1 |> printfn "%i"
I believe there is a more natural functional solution if you approach it freshly, but I wanted to evolve your current solution.
(我相信,如果您刚开始使用,将有一个更自然的功能解决方案,但是我想发展您当前的解决方案。)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…