私はテキストノードのようなツリー構造を持っています。これは、別のテキストノードを子として持つかもしれません。その中の1つの値を更新する必要があります。そのツリーのどこかにあるテキストノードを更新する最も簡単な方法は何ですか(またはそのツリーにはまったくありません)。再帰型の値を更新する - elm lang
不変でない言語では、単にその項目の値を変更するだけですが、それだけですが、Elmのような不変言語ではかなり難しいです。
type alias Item =
{ id: String
, text: String
, children: ChildItems
}
type ChildItems = ChildItems (List Item)
type alias Model =
{ rootItem: Item
}
updateItem: Item -> Item -> Item
updateItem: rootItem item =
-- TODO
...
update model =
case msg of
UpdateItem item updatedText ->
let
updatedItem = { item | text = updatedText }
in
({ model | rootItem = (updateItem model.rootItem updatedItem) }, Cmd.none)
これは私が
updateItem: Item.Item -> Item.Item -> Item.Item
updateItem rootItem updatedItem =
if rootItem.id == updatedItem.id then
updatedItem
else
case rootItem.children of
Item.ChildItem [] ->
rootItem
Item.ChildItem children ->
let
updatedChildren =
case children of
[] ->
[]
children ->
List.map (\item ->
updateItem rootItem item) children
in
{ rootItem | children = Item.ChildItem updatedChildren }
思い付いたものですが、私はあなたがrootItem
の代わりに戻ってきているので、あなたは、スタックオーバーフローを取得している理由があるMaximum call stack size exceeded
エラーに
優秀な回答!あなたは私の一日を作った:) –
このパターンを使ってアイテムのネストされたリストを更新するには? 私が打つ問題は、レコード更新式が、表示される関数の戻り式になるように設計されていることです。新しいItemを作成するように設計された関数は、戻り値の式はアイテムのものではなく新しいアイテムにする必要があります。私が更新する必要がある親の子供のリスト。 再帰型(別名「ツリー」)構造を扱う方法に関する聖句はありますか?アイテムの型名をエイリアスにし、コレクションを型にする方法を見てきました。あなたは別のプロトコルを提供します。 –
@RichardHavenは、map関数によって処理されます。与えられたノードからアイテムを構成し、関数によって変更された可能性のあるノードと、それが与えられたノードの子を作成します関数によって変更される可能性があります。最終的にupdateByIdをマップに渡すと、変更された1つのアイテムを除き、同じ部分を使用してノードのツリーが再帰的に構築されます。 –