[英]In F#, how to correctly use ResizeArray() and an accumulator in an Array.map to change the property of a record
(Newbie question). (新手问题)。 Simple question.
简单的问题。
In C#, I have the following code:在 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;
}
In F#, I've tried this for simplicity but it fails.在 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} )
The goal here is to calculate a new TopLeft value for each Cursor in the cursors array based on an accumalator in 'left' and return a new cursors array with each cursor record having its new value.这里的目标是根据“left”中的累加器为游标数组中的每个 Cursor 计算一个新的 TopLeft 值,并返回一个新的游标数组,其中每个 cursor 记录具有其新值。
How is this done correctly?这是如何正确完成的? Can it be done without using a mutable "left" variable?
可以在不使用可变“左”变量的情况下完成吗?
Thank you in advance.先感谢您。
#Addendum: The "columns" is defined as an array of integers (each integer representing the width of a column). #附录:“列”定义为整数数组(每个 integer 代表一列的宽度)。
columns = [|210; 330|]
I don't think you need a fold (or, to be more precise, a scan ) to handle this, because the current TopLeft
value can actually be computed without reference to the previous TopLeft
value.我认为您不需要 fold (或者更准确地说是scan )来处理这个问题,因为实际上可以在不参考之前的
TopLeft
TopLeft
。 This is a good case for an array comprehension.这是数组理解的一个很好的例子。 Something like this:
像这样的东西:
let cursors =
[|
for i = 0 to columnCount-1 do
yield { TopLeft = initialOffset + (columnOffset * float i) }
|]
This works because the columns are constant-width.这是有效的,因为列是恒定宽度的。 For variable-width columns, you would definitely need a scan, like this:
对于可变宽度列,您肯定需要扫描,如下所示:
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
The output is: 100,330,690,910
output 为:
100,330,690,910
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.