【问题标题】:F# deserializing array of arraysF#反序列化数组数组
【发布时间】:2013-04-02 14:54:37
【问题描述】:

我必须从存储为 JSON 数组的文件中读取一些数据。基本上,数据代表一棵二叉树,带有节点标签和叶子上的值,并且样式化了一条线,如下所示:

[label1,[label2,[label3,w],x],[label4,y,z]]

在所有分支上具有任意深度。现在,我最终希望将其转换为树结构,但第一步是读入它。

以下 C# 代码有效(使用 System.Web.Extensions.dll):

var jss = new JavaScriptSerializer();
foreach (string line in System.IO.File.ReadAllLines(filename))
{
    var data = jss.Deserialize<object[]>(line);
}

“作品”是指在上面给出的示例中,data.[1]又是一个对象数组。 F# 的直接端口是

let data = 
   let jss = new JavaScriptSerializer()
   System.IO.File.ReadAllLines(filename)
       |> Seq.map (fun line -> jss.Deserialize<obj[]>(line))

但是,将其应用于示例确实会产生数据。[1]是一个对象而不是一个对象数组。

我考虑将反序列化替换为

       |> Seq.map (fun line -> jss.Deserialize<seq<obj[]>(line))

但这不起作用,因为(在我的示例中)label1 是一个字符串,并且(显然)不能转换为 System.Object[]。我还尝试将 C# 代码包装在静态类中,然后使用该类读取 F# 中的数据,但这也不起作用。我知道我可以使用外部 JSON 解析器,但由于使用 JavaScriptSerializer 确实在 C# 中工作,我的固执开始了,我也想在 F# 中这样做。有什么建议吗?

【问题讨论】:

标签: arrays f# deserialization


【解决方案1】:

这对我有用:

#r "System.Web.Extensions"

open System.Web.Script.Serialization

let jss = new JavaScriptSerializer()
let data = jss.Deserialize<obj[]>("""["label1",["label2",["label3","w"],"x"],["label4","y","z"]]""")
let doesItWork = data.[1].GetType() = typeof<obj[]>

您能否提供一个更完整的示例来说明什么不适合您?

【讨论】:

  • 我现在可以访问的 PC 不支持 F# 3.0,所以三重引号字符串对我不起作用。然而,对我来说,data.[1].GetType() = typeof&lt;obj[]&gt; 也返回 true,但同时像 (data.[1]).[0] 这样的东西不起作用,尽管 (data.[1] :?&gt; obj[]).[0] 起作用。将此标记为已回答,因为我将在其余的数据检索中进行转换,但不确定我是否理解行为与 C# 的差异。
  • @Bram - 我很惊讶您的 C# 代码也不需要相应的强制转换(除非您在某处使用 dynamic)。
  • 我没有在任何地方的 C# 代码中使用 dynamic。无论如何,我想做的工作现在正在工作,暂时我不会去追究造成差异的原因:时间太少,对 MSIL 的了解也太少,无法比较两者。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多