【发布时间】:2011-04-17 05:18:56
【问题描述】:
如果有人想要记录类型,我会留下以下内容,但我的问题可以如下提出。 假设需要将一个可以为空的记录类型写入文件,考虑到以下产生的最佳方法是什么:“'Basic' 类型没有'null' 作为正确值”:
type Basic = {Toto:string}
let basicToString b = function
|null -> "null"
|record->record.Toto
非常感谢
我有以下代码来反序列化 Twitter 流中的推文:
open System.Runtime.Serialization
open System.Runtime.Serialization.Json
open System
open System.Text
open System.IO
let makeString numFields =
if numFields>1 then
seq[for i in 1..(numFields-1)->","]
|> Seq.fold(fun elem res-> elem+res) ""
else
""
[<DataContract>]
type boundingbox = {
[<field: DataMember(Name = "type")>]
t:string
[<field: DataMember(Name = "coordinates")>]
coordinates:float array array array
}
with
member this.ToCsv() = let temp = string this
if temp ="" then
makeString 2
else
this.t+","+"coordinates"
[<DataContract>]
type attributes = {
[<field: DataMember(Name = "street_adress")>]
street_adress:string
}
with
member this.ToCsv() = let temp = string this
if temp ="" then
makeString 1
else
this.street_adress
[<DataContract>]
type place = {
[<field: DataMember(Name = "country")>]
country:string
[<field: DataMember(Name = "url")>]
url:string
[<field: DataMember(Name = "attributes")>]
attributes:attributes
[<field: DataMember(Name = "country_code")>]
country_code:string
[<field: DataMember(Name = "full_name")>]
full_name:string
[<field: DataMember(Name = "name")>]
name:string
[<field: DataMember(Name = "id")>]
id:string
[<field: DataMember(Name = "bounding_box")>]
bounding_box:boundingbox
[<field: DataMember(Name = "pldace_type")>]
place_type:string
}
with
member this.toCsv() = let temp = string this
if temp ="" then
makeString 10
else
this.country+","+this.url+","+this.attributes.ToCsv()+","+this.country_code+","+this.full_name+","+this.name+","+this.bounding_box.ToCsv()+","+this.place_type
[<DataContract>]
type geo = {
[<field: DataMember(Name = "type")>]
t:string
[<field: DataMember(Name = "coordinates")>]
coordinates:float array
}
[<DataContract>]
type url = {
[<field: DataMember(Name = "url")>]
url:string
[<field: DataMember(Name = "indices")>]
indices:int array
}
[<DataContract>]
type hashtag = {
[<field: DataMember(Name = "text")>]
text:string
[<field: DataMember(Name = "indices")>]
indices:int array
}
[<DataContract>]
type user_mention = {
[<field: DataMember(Name = "indices")>]
indices:int array
[<field: DataMember(Name = "screen_name")>]
screen_name:string
[<field: DataMember(Name = "name")>]
name:string
[<field: DataMember(Name = "id")>]
id:string
}
[<DataContract>]
type entities = {
[<field: DataMember(Name = "urls")>]
urls:url array
[<field: DataMember(Name = "hashtags")>]
hashtags:hashtag array
[<field: DataMember(Name = "user_mentions")>]
user_mentions:user_mention array
}
[<DataContract>]
type user = {
[<field: DataMember(Name = "time_zone")>]
time_zone:string
[<field: DataMember(Name = "profile_sidebar_border_color")>]
profile_sidebar_border_color:string
[<field: DataMember(Name = "screen_name")>]
screen_name:string
[<field: DataMember(Name = "notifications")>]
notifications:string
[<field: DataMember(Name = "listed_count")>]
listed_count:string
[<field: DataMember(Name = "profile_background_image_url")>]
profile_background_image_url:string
[<field: DataMember(Name = "location")>]
location:string
[<field: DataMember(Name = "statuses_count")>]
statuses_count:string
[<field: DataMember(Name = "profile_background_color")>]
profile_background_color:string
[<field: DataMember(Name = "description")>]
description:string
[<field: DataMember(Name = "show_all_inline_media")>]
show_all_inline_media:string
[<field: DataMember(Name = "profile_background_tile")>]
profile_background_tile:string
[<field: DataMember(Name = "contributors_enabled")>]
contributors_enabled:string
[<field: DataMember(Name = "geo_enabled")>]
geo_enabled:string
[<field: DataMember(Name = "created_at")>]
created_at:string
[<field: DataMember(Name = "profile_text_color")>]
profile_text_color:string
[<field: DataMember(Name = "followers_count")>]
followers_count:string
[<field: DataMember(Name = "profile_use_background_image")>]
profile_use_background_image:string
[<field: DataMember(Name = "url")>]
url:string
[<field: DataMember(Name = "friends_count")>]
friends_count:string
[<field: DataMember(Name = "profile_link_color")>]
profile_link_color:string
[<field: DataMember(Name = "protected")>]
Protected:string
[<field: DataMember(Name = "lang")>]
lang:string
[<field: DataMember(Name = "verified")>]
verified:string
[<field: DataMember(Name = "name")>]
name:string
[<field: DataMember(Name = "follow_request_sent")>]
follow_request_sent:string
[<field: DataMember(Name = "following")>]
following:string
[<field: DataMember(Name = "favourites_count")>]
favourites_count:string
[<field: DataMember(Name = "profile_sidebar_fill_color")>]
profile_sidebar_fill_color:string
[<field: DataMember(Name = "profile_image_url")>]
profile_image_url:string
[<field: DataMember(Name = "id")>]
id:string
[<field: DataMember(Name = "utc_offset")>]
utc_offset:string
}
[<DataContract>]
type tweet = {
[<field: DataMember(Name = "place")>]
place:place
[<field: DataMember(Name = "geo")>]
geo:geo
[<field: DataMember(Name = "text")>]
text:string
[<field: DataMember(Name = "coordinates")>]
coordinates:geo
[<field: DataMember(Name = "retweet_count")>]
retweet_count:string
[<field: DataMember(Name = "favorited")>]
favorited:string
[<field: DataMember(Name = "source")>]
source:string
[<field: DataMember(Name = "contributors")>]
contributors:int array
[<field: DataMember(Name = "created_at")>]
created_at:string
[<field: DataMember(Name = "in_reply_to_status_id")>]
in_reply_to_status_id:string
[<field: DataMember(Name = "in_reply_to_screen_name")>]
in_reply_to_screen_name:string
[<field: DataMember(Name = "user")>]
user:user
[<field: DataMember(Name = "retweeted")>]
retweeted:string
[<field: DataMember(Name = "in_reply_to_user_id")>]
in_reply_to_user_id:string
[<field: DataMember(Name = "truncated")>]
truncated:string
[<field: DataMember(Name = "id")>]
tweet_id:string
[<field: DataMember(Name = "entities")>]
entities:entities
}
[<DataContract>]
type fullTweet = {
[<field: DataMember(Name = "place")>]
place:place
[<field: DataMember(Name = "geo")>]
geo:geo
[<field: DataMember(Name = "text")>]
text:string
[<field: DataMember(Name = "coordinates")>]
coordinates:geo
[<field: DataMember(Name = "retweet_count")>]
retweet_count:string
[<field: DataMember(Name = "favorited")>]
favorited:string
[<field: DataMember(Name = "source")>]
source:string
[<field: DataMember(Name = "contributors")>]
contributors:int array
[<field: DataMember(Name = "created_at")>]
created_at:string
[<field: DataMember(Name = "in_reply_to_status_id")>]
in_reply_to_status_id:string
[<field: DataMember(Name="retweeted_status")>]
retweeted_status:tweet
[<field: DataMember(Name = "in_reply_to_screen_name")>]
in_reply_to_screen_name:string
[<field: DataMember(Name = "user")>]
user:user
[<field: DataMember(Name = "retweeted")>]
retweeted:string
[<field: DataMember(Name = "in_reply_to_user_id")>]
in_reply_to_user_id:string
[<field: DataMember(Name = "truncated")>]
truncated:string
[<field: DataMember(Name = "id")>]
tweet_id:string
[<field: DataMember(Name = "entities")>]
entities:entities
}
let decodeFullTweet (s:string) =
let json = new DataContractJsonSerializer(typeof<fullTweet>)
let byteArray = Encoding.UTF8.GetBytes(s)
let stream = new MemoryStream(byteArray)
json.ReadObject(stream) :?>fullTweet
let decodeUser (s:string) =
let json = new DataContractJsonSerializer(typeof<user>)
let byteArray = Encoding.UTF8.GetBytes(s)
let stream = new MemoryStream(byteArray)
json.ReadObject(stream) :?>user
我需要完成的下一步是将每个 fullTweet 记录写入 csv 文件,问题是有时记录类型的某些字段为空。比如解码json字符串时(下面只是一小部分字符串):
rel=\\"nofollow\\">TweetDeck\",\"favorited\":false,\"in_reply_to_status_id\":null,\"entities\":{\"hashtags\":[{\" text\":\"frac1\",\"indices\":[117,123]}],\"user_mentions\":[],\"urls\":[]},\"place\":null,\ "坐标\":null,\"geo\":null,\"in_reply_to_user_id\":null,\"
“place”和“in_reply_to_user_id”字段将为空。
我该如何处理,以便当字段为空(例如地点)时,csv 行读取“null”(对于记录类型地点的每个字段)?或者如果你有更好的方法来处理这个?
非常感谢!!!
(希望有些人会喜欢所有的记录类型:))
【问题讨论】:
-
您是否已经有一些代码或想法如何生成 CSV 文件?否则,这个问题很难回答。如何处理空值取决于 CSV 文件的创建方式。
-
@wmeyer 感谢您查看此内容。我的问题不是很清楚,抱歉。我用一个“有效”的解决方案编辑了我的帖子,但它看起来有点难看。
-
对您的问题没有答案,但发现您在 makeString 函数中对折叠的使用非常巧妙。但是,如果你想把它留给 F# 库,你可以使用 'let makeString numFields = String.init numFields (fun _ -> ",")' 代替。
-
@Alexander Rautenberg 感谢您的提示,使用 String.init 是一个更好的解决方案