[英]In F#, how to correctly use ResizeArray() and an accumulator in an Array.map to change the property of a record
(新手問題)。 簡單的問題。
在 C# 中,我有以下代碼:
double openspace = (WorkArea.Width - totalcolumnwidth) / (ColumnCount - 1);
double left = WorkArea.Left;
for (int k = 0; k < ColumnCount; k++)
{
Cursor cursor = new Cursor
{
TopLeft = new Point(left, WorkArea.Top),
};
cursors.Add(cursor);
left += Columns[k] + openspace;
}
在 F# 中,為了簡單起見,我已經嘗試過了,但它失敗了。
type Cursor = { TopLeft: float }
let columnCount = 5.0 // // columnCount number of cursors in List<Cursor>
let cursors = new ResizeArray<Cursor>(columnCount)
let mutable left = 20.0
cursors |> Array.map ( fun k -> left <- left + 10 + k.TopLeft ; {k with TopLeft = left} )
這里的目標是根據“left”中的累加器為游標數組中的每個 Cursor 計算一個新的 TopLeft 值,並返回一個新的游標數組,其中每個 cursor 記錄具有其新值。
這是如何正確完成的? 可以在不使用可變“左”變量的情況下完成嗎?
先感謝您。
#附錄:“列”定義為整數數組(每個 integer 代表一列的寬度)。
columns = [|210; 330|]
我認為您不需要 fold (或者更准確地說是scan )來處理這個問題,因為實際上可以在不參考之前的TopLeft
TopLeft
。 這是數組理解的一個很好的例子。 像這樣的東西:
let cursors =
[|
for i = 0 to columnCount-1 do
yield { TopLeft = initialOffset + (columnOffset * float i) }
|]
這是有效的,因為列是恆定寬度的。 對於可變寬度列,您肯定需要掃描,如下所示:
let columnWidths = [| 210; 340; 200; 300 |]
let initialOffset = 100 // left coord of first column
let columnOffset = 20 // gap between columns
let columnLefts =
(initialOffset, columnWidths)
||> Seq.scan (fun acc width ->
acc + width + columnOffset)
|> Seq.take columnWidths.Length // ignore final value
|> Seq.toArray
printfn "%A" columnLefts
output 為: 100,330,690,910
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.