.net - 为什么我的 F# 函数在使用 Array.iter 时会导致越界错误?

标签 .net arrays f#

我有一个函数,其中 Array.iter 用于在应用函数后打印嵌套数组 (z) 的第 4 个元素。我正在输入一个由“\n”分隔的长字符串,然后是“”的(嵌套)分隔符。它似乎迭代到更高级别数组 (y) 的末尾之外。

let digestMDtest (x : string) =
    let y = x.Split '\n' |> Array.tail
    let mapMD (x : string) =
        let z = x.Split '"'
        printfn "%s" z.[3]
    Array.iter mapMD y

我收到错误,您可以看到我输入的数据的最后 3 个时间戳,“2016-04-15T15:59:00-04:00”是最后一个元素,似乎超越它。

2016-04-15T15:57:00-04:00
2016-04-15T15:58:00-04:00
2016-04-15T15:59:00-04:00
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at FSI_0002.mapMD@69-1(String x) in C:\OneDrive\FSMDC.barchart.fsx:line 70
   at FSI_0002.digestMDtest(String x) in C:\OneDrive\FMDC.barchart.fsx:line 72

在我看来,Array.iter 函数试图迭代超出数组末尾的数组元素。它为什么要这样做?我只能假设 Array.tai​​l 与它有关;也许 Array.iter 使用的是数组的原始大小而不是当前大小?

最佳答案

鉴于您对输入数据的书面描述,我创建了一个这样的示例设置(如果我误解了您的描述,请告诉我!):

let data = "\"2016-04-15T15:57:00-04:00\"\n\"2016-04-15T15:58:00-04:00\"\n\"2016-04-15T15:59:00-04:00\""

假设我的数据与您的大致匹配,您将跳过第一个值,然后 Array.iter 处理其余两个值:

"2016-04-15T15:58:00-04:00"
"2016-04-15T15:59:00-04:00"

然后你在每个元素上调用这个函数:

let mapMD (x : string) =
    let z = x.Split '"'
    printfn "%s" z.[3]

对这些字符串调用 Split 会得到如下所示的结果:

[|"", date, ""|]

您从该数组中索引元素 .[3] 但只有 3 个元素,因此这将在每个元素上触发 IndexOutOfRangeException

索引元素一般来说不是函数式编程中的好模式,使用可以使意图更明确的模式通常更好。

例如,如果我在这种情况下尝试提取日期字符串,我会这样做:

let mapMD (x : string) =
    match x.Split '"' with
    |[|_; date; _|] -> printfn "%s" date
    |_ -> raise <| FormatException("Invalid Date String Format")

可以看到这里,模式匹配简洁的描述了字符串数组的预期格式。

关于.net - 为什么我的 F# 函数在使用 Array.iter 时会导致越界错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36700271/

相关文章:

f# - 是一个 "optionalized"管道操作符惯用的 F#

.net - 这会导致内存泄漏(在 .NET 中)吗?

.net - Silverlight:将子控件属性绑定(bind)到用户控件中的属性

javascript - 按顺序将数组值附加到多个 div

c++ - 越界访问数组不会出错,为什么?

generics - F#:尝试通过界面复制和更新记录时出错

f# - 在 F# 中处理 Deedle 时间序列中的缺失值(三)

c# - 压缩 WCF 的所有流量

返回 http 状态代码 400(错误请求)时,.Net HttpWebRequest.GetResponse() 引发异常

c++ - 使用值列表的模板数组初始化