我是F#的新手, 我有一个包含数组的列表,每个数组包含7个字符串。 我想遍历数组并稍后再做某种Array.map,
但是我的问题是我无法将单个数组发送到其他函数。
我不想使用for循环,而是专注于仅使用管道和映射的功能方式。
let stockArray =
[[|"2012-03-30"; "32.40"; "32.41"; "32.04"; "32.26"; "31749400"; "32.26"|];
[|"2012-03-29"; "32.06"; "32.19"; "31.81"; "32.12"; "37038500"; "32.12"|];
[|"2012-03-28"; "32.52"; "32.70"; "32.04"; "32.19"; "41344800"; "32.19"|];
[|"2012-03-27"; "32.65"; "32.70"; "32.40"; "32.52"; "36274900"; "32.52"|];]
let tryout =
stockArray
|> List.iter;;
输出抱怨List.iter:
error FS0001: Type mismatch. Expecting a
'string [] list -> 'a' but given a
'('b -> unit) -> 'b list -> unit'
The type 'string [] list' does not match the type ''a -> unit'
尝试Array.iter时,有相同的区别:
error FS0001: Type mismatch. Expecting a
'string [] list -> 'a' but given a
'('b -> unit) -> 'b [] -> unit'
The type 'string [] list' does not match the type ''a -> unit'
在C#中,我会简单地使用foreach进行处理,以一次开始处理我的数组,但是在使用F#时,我真的感到很困惑。
感谢您的帮助
答案 0 :(得分:1)
即使有其他注释,问题也不清楚。无论如何,我认为您终于可以从此答案中找出您的需求。
我已经以这样的方式实现了parseDate和parseFloat,我希望它可以在给定数据的任何计算机上工作,无论是哪种语言环境。您可能需要其他一些用于生产应用程序的内容。另外,InIn的计算方式可能不是您想要的。
您已经发现, List.iter将数据转换为unit
,有效地丢弃了数据。那有什么意义呢?通常将其放在管道序列中时放在最后,经常做一些涉及副作用(例如打印数据)或可变数据操作(例如用项目填充可变列表)的工作。我建议您研究“列表”,“数组”,“序列”和“选项”模块中的函数,以了解它们如何用于转换数据。
open System
open System.Globalization
let stockArray =
[
[| "2012-03-30"; "32.40"; "32.41"; "32.04"; "32.26"; "31749400"; "32.26" |]
[| "2012-03-29"; "32.06"; "32.19"; "31.81"; "32.12"; "37038500"; "32.12" |]
[| "2012-03-28"; "32.52"; "32.70"; "32.04"; "32.19"; "41344800"; "32.19" |]
[| "2012-03-27"; "32.65"; "32.70"; "32.40"; "32.52"; "36274900"; "32.52" |]
]
type OutData = { TheDate: DateTime; TheInt: int }
let parseDate s = DateTime.ParseExact (s, "yyyy-MM-dd", CultureInfo.InvariantCulture)
let parseFloat s = Double.Parse (s, CultureInfo.InvariantCulture)
let myFirstMap (inArray: string[]) : OutData =
if inArray.Length <> 7 then
failwith "Expected array with seven strings."
else
let theDate = parseDate inArray.[0]
let f2 = parseFloat inArray.[2]
let f3 = parseFloat inArray.[3]
let f = f2 - f3
let theInt = int f
{ TheDate = theDate; TheInt = theInt }
let tryout =
stockArray
|> List.map myFirstMap
以下是myFirstMap的替代实现。我想有些人会说这更惯用,但我只是想说,您更喜欢使用什么取决于对未来可能的开发的期望。
let myFirstMap inArray =
match inArray with
| [| sDate; _; s2; s3; _; _; _ |] ->
let theDate = parseDate sDate
let f2 = parseFloat s2
let f3 = parseFloat s3
let f = f2 - f3
let theInt = int f
{ TheDate = theDate; TheInt = theInt }
| _ -> failwith "Expected array with seven strings."
答案 1 :(得分:0)
管道运算符|>
用于将f x
编写为x |> f
。
List.iter
的签名是:
action: ('a -> unit) -> list: ('a list) -> unit
您给它一个操作,然后一个列表,它给您一个 void 。
您可以这样阅读:给List.iter
做一个动作时,其类型将为
list: ('a list) -> unit
可以向其传递列表的功能。
因此,当您编写stockArray |> List.iter
时,实际上是在尝试代替操作的是列表-这就是错误。因此,传递一个动作:
let tryout = List.iter (fun arr -> printfn "%A" arr) stockArray
可以改写为:
let tryout = stockArray |> List.iter (fun arr -> printfn "%A" arr)
答案 2 :(得分:0)
但是我的问题是我无法将单个数组发送到其他函数
List.map
和类似的函数使您可以精确地执行此操作-无需自己迭代列表。
例如,这将仅返回列表中每个数组的第一个元素:
stockArray
|> List.map (fun x -> x.[0])
您可以将传递给List.map的函数替换为对一个数组进行操作并返回一些值的任何函数。