gpt4 book ai didi

algorithm - F# 从元组到枚举列表的转换

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:02:41 26 4
gpt4 key购买 nike

以下代码源自欧氏距离算法。颜色表只是测试算法的工具。它可能是在重新发明轮子,但它本身很有用。任何 3 个 RGB 整数 (0-255) 都可以与最接近的 X11 颜色名称相关联。非常感谢 svick他的见解。

在当前代码中,ColorTable 在创建实例后通过 AddColor 方法进行初始化。但是,loadrgb/colorinfo 组合可用于从网络上下载 X11 颜色表。

我在从 X11 rgb.txt 文件的在线版本初始化颜色表时遇到最后一个问题。我需要将文本解析为 {Name: Values:} 列表。目前,结果在一个字符串元组中。我正在努力让“colorinfo”加载“ColorTable”。

// currently the color table is create via the AddColor method, however
// the initial values should be created with the loadrgb and colorinfo members
type MyFSColorTable() =

// pull the X11 rgb.txt color table off the web in text format
static let loadrgb =
let url = "http://people.csail.mit.edu/jaffer/Color/rgb.txt"
let req = WebRequest.Create(url)
let resp = req.GetResponse()
let stream = resp.GetResponseStream()
let reader = new StreamReader(stream)
let txt = reader.ReadToEnd()
txt

// parse the text of the rgb.txt color table into a Name: Values: list
static let colorinfo =
loadrgb.Split([|'\n'|])
|> Seq.skip 1
|> Seq.map (fun line -> line.Split([|'\t'|]))
|> Seq.filter (fun values -> values |> Seq.length = 3)
|> Seq.map (fun values -> string values.[0], string values.[2])
|> Seq.map (fun (rgb, name) -> rgb.Split([|' '|]), name)
|> Seq.map (fun (rgb, name) -> [|name, rgb.[0], rgb.[1], rgb.[2]|])

// Mutable Color Table will be defined on-the-fly
let mutable ColorTable = []
// Euclidean distance between 2 vectors - float is overkill here
static let Dist (V1: float[]) V2 =
Array.zip V1 V2
|> Array.map (fun (v1, v2) -> pown (v1 - v2) 2)
|> Array.sum

// Add new colors to the head of the ColorTable
member x.AddColor name rgb = ColorTable <- {Name = name; Values = rgb}::ColorTable

// Find nearest color by calculating euclidean distance of all colors,
// then calling List.minBy for the smallest
member x.FindNearestColor (rgb : float[]) =
let nearestColor =
ColorTable |> List.minBy (fun color -> Dist rgb color.Values)
nearestColor.Name

最佳答案

目前,您构造 colorinfo 的代码生成一个包含数组的序列,其中只有一个元素是一个元组(包含四个字符串)。这意味着总体结果的类型是 - 在您当前的版本中 - seq<(string * string * string * string) []> :

  (...)
|> Seq.map (fun (rgb, name) ->
[|name, rgb.[0], rgb.[1], rgb.[2] |]

这可能不是故意的 - 如果您想创建一个包含四个字符串的数组,您需要使用分号而不是逗号 [| name; rgb.[0]; ... |]如果你想创建四元素元组,那么你可以省略 [||]围绕元组。

没有办法自动将数组或元组转换为命名记录类型(假设您有一条包含 Name:stringValues:float[] 的记录),因此最好的选择是在您的最后一步进行此转换管道。您可以将上面的替换为:

  |> Seq.map (fun (rgb, name) -> 
{ Name = name
Values = [| float rgb.[0]; float rgb.[1]; float rgb.[2] |] })
|> List.ofSeq

我还添加了 List.ofSeq到代码段的末尾,以便您获得一个列表 - 这与您用于 ColorTable 的类型相同此刻。

(或者,您可以说 Values = Array.map float rgb ,它将 rgb 中的所有字符串转换为 float 并适用于数组的任何长度。)

关于algorithm - F# 从元组到枚举列表的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14734658/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com