用榆树中的新数据更新嵌套记录
Updating a nested record with new data in elm
我有两段 JSON 已按顺序成功解码。我想使用新的 html_fragment
并更新我现有的 html_fragment
。通常这很简单,但我的数据结构给我带来了困难:
type PostDataContainer
= PostDataContainer PostData
type alias PostData =
{ title : String
, comments : List Comment
}
type alias Comment =
{ comment_id : Int
, html_fragment : String
}
type alias CommentHtml =
{ id : Int
, html_fragment : String
}
我刚刚获得 CommentHtml
并想更新 Comment
中现有的 html_fragment
。这是我目前所拥有的:
MergeCommentHtml commentHtmlData ->
case commentHtmlData of
Err err ->
Debug.log ("Error decoding CommentHtmlData" ++ toString err)
( mdl, Cmd.none )
Ok commentHtml ->
case mdl.maybePostDataContainer of
Just (PostDataContainer postData) ->
let
updatedCommentData = -- I dont know how to calculate this?
in
( { mdl | postData = { postData | comments = updatedCommentData } }, Cmd.none )
注意这里的commentHtml
是一个List CommentHtml
。关于如何用 commentHtml
中的新值更新我的旧 comment.html_fragment
有什么想法吗?
选项 1:
只需按原样解码数据。当需要显示它时,通过你写的一些函数适当地排列它,比如 rawJsonDataToNicerData
。
选项 2:
假设您实现了以下功能:
-- given a new comment, and some PostData, return the new version of the PostData
updateData : CommentHtml -> PostData -> PostData
-- so now, assuming we can decode a CommentHtml with commentHtmlDeocder
-- we can do the following
dataUpdaterDecoder : Decoder (PostData -> PostData)
dataUpdaterDecoder
commentHtmlDecoder |> Decoder.andThen (\commentHtml -> updateData commentHtml)
现在,无论我们要解码 commentHtmlDeocder
,我们都可以解码 dataUpdaterDecoder
,并使用其中的一堆来更新我们的数据。
下面是一个使用上述想法的关系数据解码器的例子:
鉴于commentHtmlData
根据评论是List
,我认为最简单的方法是将其转换为id
键控的Dict
,然后映射在字典中寻找 comment_id
的现有评论。如果存在则替换html_fragment
,如果不存在则return原未修改的:
let
commentHtmlDict =
commentHtmlData
|> List.map (\c -> (c.id, c))
|> Dict.fromList
updatedCommentData =
postData.comments
|> List.map (\comment ->
case Dict.get comment.comment_id commentHtmlDict of
Just commentHtml ->
{ comment | html_fragment = commentHtml.html_fragment }
Nothing ->
comment
)
我有两段 JSON 已按顺序成功解码。我想使用新的 html_fragment
并更新我现有的 html_fragment
。通常这很简单,但我的数据结构给我带来了困难:
type PostDataContainer
= PostDataContainer PostData
type alias PostData =
{ title : String
, comments : List Comment
}
type alias Comment =
{ comment_id : Int
, html_fragment : String
}
type alias CommentHtml =
{ id : Int
, html_fragment : String
}
我刚刚获得 CommentHtml
并想更新 Comment
中现有的 html_fragment
。这是我目前所拥有的:
MergeCommentHtml commentHtmlData ->
case commentHtmlData of
Err err ->
Debug.log ("Error decoding CommentHtmlData" ++ toString err)
( mdl, Cmd.none )
Ok commentHtml ->
case mdl.maybePostDataContainer of
Just (PostDataContainer postData) ->
let
updatedCommentData = -- I dont know how to calculate this?
in
( { mdl | postData = { postData | comments = updatedCommentData } }, Cmd.none )
注意这里的commentHtml
是一个List CommentHtml
。关于如何用 commentHtml
中的新值更新我的旧 comment.html_fragment
有什么想法吗?
选项 1:
只需按原样解码数据。当需要显示它时,通过你写的一些函数适当地排列它,比如 rawJsonDataToNicerData
。
选项 2:
假设您实现了以下功能:
-- given a new comment, and some PostData, return the new version of the PostData
updateData : CommentHtml -> PostData -> PostData
-- so now, assuming we can decode a CommentHtml with commentHtmlDeocder
-- we can do the following
dataUpdaterDecoder : Decoder (PostData -> PostData)
dataUpdaterDecoder
commentHtmlDecoder |> Decoder.andThen (\commentHtml -> updateData commentHtml)
现在,无论我们要解码 commentHtmlDeocder
,我们都可以解码 dataUpdaterDecoder
,并使用其中的一堆来更新我们的数据。
下面是一个使用上述想法的关系数据解码器的例子:
鉴于commentHtmlData
根据评论是List
,我认为最简单的方法是将其转换为id
键控的Dict
,然后映射在字典中寻找 comment_id
的现有评论。如果存在则替换html_fragment
,如果不存在则return原未修改的:
let
commentHtmlDict =
commentHtmlData
|> List.map (\c -> (c.id, c))
|> Dict.fromList
updatedCommentData =
postData.comments
|> List.map (\comment ->
case Dict.get comment.comment_id commentHtmlDict of
Just commentHtml ->
{ comment | html_fragment = commentHtml.html_fragment }
Nothing ->
comment
)