Je laisse le ci-dessous au cas où quelqu'un veut les types d'enregistrement, mais ma question peut être posée comme suit. Supposons que l'on doive écrire dans un fichier un type d'enregistrement pouvant être nul, quelle est la meilleure façon d'y parvenir, compte tenu des rendements ci-dessous: "Le type 'Basic' n'a pas de valeur nulle":Deserializing flux twitter json chaîne F #, comment définir «nul» comme une valeur correcte?
type Basic = {Toto:string}
let basicToString b = function
|null -> "null"
|record->record.Toto
Merci beaucoup
je le code suivant à désérialiser tweets de flux 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
l'étape suivante où je dois se faire est de wr ite chaque enregistrement fullTweet à un fichier csv, le problème est que parfois certains des champs du type d'enregistrement sont null. Par exemple lors du décodage de la chaîne JSON (ci-dessous est juste une petite partie de la chaîne):
rel = \\ "nofollow \\"> TweetDeck \ ", \" favorisé \ ": false, \" in_reply_to_status_id \ ": null, \" entités \ ": {\" hashtags \ ": [{\" text \ ": \" frac1 \ ", \" indices \ ": [117,123]}], \" user_mentions \ ": [ ], \ "urls \": []}, \ "place \": null, \ "coordonnées \": null, \ "geo \": null, \ "in_reply_to_user_id \": null, \ "
Les champs "place" et "in_reply_to_user_id" seront null.
Comment puis-je gérer cela de telle sorte que lorsqu'un champ est nul (par exemple des lieux), la ligne csv indique "null" (pour chaque champ de l'endroit du type d'enregistrement)? Ou si vous avez une meilleure façon de gérer cela?
Merci beaucoup!
(Hope certains vont profiter de tous les types d'enregistrement :))
Avez-vous déjà du code ou une idée pour générer le fichier CSV? Sinon, la question est difficile à répondre. La gestion des valeurs NULL dépend de la création du fichier CSV. – wmeyer
@wmeyer Merci de votre visite. Ma question n'est pas très claire, désolé. J'ai édité mon post avec une solution qui "fonctionne" mais elle semble un peu moche. – jlezard
N'avez pas de réponse à votre question, mais trouvez votre utilisation du pliage dans la fonction makeString très ingénieuse. Cependant, si vous voulez laisser cela à la bibliothèque F #, vous pouvez utiliser 'let makeString numFields = String.init numFields (fun _ -> ",")' à la place. –