解析字符串数组中的值

鲍勃森

我正在尝试为已绘制到表单中的2d对象创建一个保存/加载功能。

type circle = { X : int; Y : int; Diameter : int; Brush : Brush}
type Square = { X : int; Y : int; Length : int; Height: int; Brush : Brush}

当我创建对象时,我将它们放入每种类型的2个列表1中。我最初的想法是将这些对象读取并写入文本文件,请参见下文:

saveFile.Click.Add(fun _ ->
 for c in listOfCircles do 
   myfile.WriteLine("Circle," + c.X.ToString() + "," + c.Y.ToString() + "," + c.Diameter.ToString() + "," + c.Brush.ToString())
 for s in listOfSquares do
   myfile.WriteLine("Square," + s.X.ToString() + "," + s.Y.ToString() + "," + s.Height.ToString() + "," + s.Length.ToString() + "," + s.Brush.ToString())
 myfile.Close() // close the file

在文本文件中看起来像这样

Circle,200,200,50,System.Drawing.SolidBrush
Square,50,55,45,55,System.Drawing.SolidBrush

从这里我想读取这些值,然后能够解析它们,并通过将对象添加到列表中并重新绘制它们来重新创建对象。

let readCircle =
  System.IO.File.ReadAllLines path
  |> Array.choose (fun s ->
    match s.Split ',' with
    | [|x; y ; z ; b ; _|] when x = "Circle" -> Some (y, z, b)
    | _ -> None )

let readSquare =  
  System.IO.File.ReadAllLines path
  |> Array.choose (fun s ->
    match s.Split ',' with
    | [|x; y ; z ; b ; a ; _|] when x = "Square" -> Some (y, z, b, a)
    | _ -> None )

这些功能给我

val readCircle : (string * string * string) [] = [|("200", "200", "50")|]
val readSquare : (string * string * string * string) [] = [|("50", "55", "45", "55")|]

我现在遇到的问题是我不确定如何从数组中获取值。下面是带有多个圆圈的示例。

val readCircle : (string * string * string) [] =  [|("200", "200", "50"); ("200", "200","50")|]

非常感谢您关于如何从此处/如何解决此问题的任何想法或意见!问题摘要:如何从数组中获取值并将其放入例如我已经创建的添加函数中,请参见下文:

 listOfCircles.Add({ X = 200; Y = 200; Diameter = 50; Brush = Brushes.Black})
叶花环

您可以使用转换字符串数组的数组Array.map,例如

[|("200", "200", "50"); ("200", "200","50")|]
|> Array.map (fun (x,y,d) -> {X = int32 x; Y = int32 y; Diameter = int32 d; Brush = Brushes.Black})

如果您转换为circlesquare解析文件时,可能会更清楚一点,那么您将拥有一个数组circle或一个数组square,可以直接将它们添加到列表中。

let readCircle =
  System.IO.File.ReadAllLines path
  |> Array.choose (fun s ->
    match s.Split ',' with
    | [|t; x; y; d; _|] when t = "Circle" -> 
        Some {X = int32 x; Y = int32 y; Diameter = int32 d; Brush = Brushes.Red}
    | _ -> None )

但是...如果您想进行更大的更改,则可以使用区分的并集来表示形状,然后它们将共享一种通用类型,Shape并且可以在同一函数中解析圆形和正方形。

type Shape = 
| Circle of X : int * Y : int * Diameter : int * Brush : Brush
| Square of X : int * Y : int * Length : int * Height: int * Brush : Brush 

let readShapes (data: string array) =
  data
  |> Array.choose (fun s ->
    match s.Split ',' with
    | [|t; x; y; d; _|] when t = "Circle" -> 
        Some (Circle(X = int32 x, Y = int32 y, Diameter = int32 d, Brush = Brushes.Red))
    | [|t; x; y; l; h; _|] when t = "Square" -> 
        Some (Square(X = int32 x, Y = int32 y, Length = int32 l, Height = int32 h, Brush = Brushes.Red))
    | _ -> None )

let listOfShapes = ResizeArray<_>()

let testInput = """
Circle,200,200,50,System.Drawing.SolidBrush
Square,50,55,45,55,System.Drawing.SolidBrush"""

testInput.Split('\n') // System.IO.File.ReadAllLines path
|> readShapes
|> Array.iter (listOfShapes.Add)

这将导致

val it : System.Collections.Generic.List<Shape> =
  seq
    [Circle (200,200,50,System.Drawing.SolidBrush {Color = Color [Red];});
     Square (50,55,45,55,System.Drawing.SolidBrush {Color = Color [Red];})]

然后,您可以使用图案匹配来绘制每种形状

let drawShape shape =
    match shape with
    | Circle(x,y,d,b) -> 
        printfn "Pretend I just drew a circle at %d,%d with diameter %d." x y d
    | Square(x,y,l,h,b) -> 
        printfn "Pretend I just drew a rectangle at %d,%d that was %d long and %d high." x y l h

listOfShapes |> Seq.iter drawShape

给予

Pretend I just drew a circle at 200,200 with diameter 50.
Pretend I just drew a rectangle at 50,55 that was 45 long and 55 high.

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章