Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: beginner 02. 04. 2017, 16:02:20
-
Mám takýto retazec:
- polozka1
- polozka2
- polozka3
- polozka4
a potreboval by som z neho urobiť strom zanorených položiek takéhoto typu type Node = Node { text : String, children : List Node }
zanorené podľa počtu tabulátorov.
import String
import List
strReplace : String -> String -> String -> String
strReplace oldValue newValue input =
input
|> String.split oldValue
|> String.join newValue
strReplaceAll : List (String, String) -> String -> String
strReplaceAll replacements input =
case replacements of
[] -> input
(oldValue, newValue) :: replacements ->
strReplaceAll replacements (input |> strReplace oldValue newValue)
unifyEols : String -> String
unifyEols =
strReplaceAll
[
("\r\n", "\n"),
("\n\r", "\n"),
("\r", "\n")
] >> \str ->
if str |> String.endsWith "\n"
then str
else str ++ "\n"
toIdentList : String -> List (Int, String)
toIdentList input =
let asString = List.reverse >> String.fromList >> String.trim in
let parseIdent count input =
case input of
'\t' :: t -> t |> parseIdent (count + 1)
data -> (count, data) in
let parseLine acc input =
case input of
'\n' :: t -> (acc, t)
h :: t -> t |> parseLine (h :: acc)
[] -> (acc, []) in
let parse acc input =
case input of
[] -> acc
data ->
let (ident, tail1) = data |> parseIdent 0 in
let (chars, tail2) = tail1 |> parseLine [] in
tail2 |> parse ((ident, chars |> asString) :: acc) in
input
|> unifyEols
|> String.toList
|> parse []
|> List.reverse
zatiaľ mám hotovú funkciu toIdentList ktorá mi vracia zoznam položiek a ich zanorenie teda na výstupe dostanem:
[(0, "- polozka1"), (1, "- polozka2"), (2, "- polozka3"), (1, "- polozka4")]
ako to previesť na strom položiek?
-
Chytil bych se té hodnoty zanoření.
Pokud je roven, generuju sourozence.
Pokud je větší zavolám rekursivně sebe sama a předám mu tail (ocásek zatím nepřežvejkaných prvků).
Pokud je menší, vrací strom vytvořených prvků, a zbytek ocásku.
Funkce dostane jako parametr seznam těch naparsovaných prvků a vrací vytvořený podstrom, a zbytek nezpracovaných prvků.
-
Stromy = rekurze. V tvem pripade bych rovnou sel do vyvazeneho stromu pro pripadne dalsi operace. Muzes si taky zjednodusit zivot pouzitim hotove knihovny http://package.elm-lang.org/packages/zwilias/elm-tree/1.0.0/Tree-AVL
-
Stromy = rekurze. V tvem pripade bych rovnou sel do vyvazeneho stromu pro pripadne dalsi operace. Muzes si taky zjednodusit zivot pouzitim hotove knihovny http://package.elm-lang.org/packages/zwilias/elm-tree/1.0.0/Tree-AVL
to je blbost. AVL je binární strom sloužící k reprezentaci množin. On potřebuje obecný strom k reprezentaci té jeho struktury.
-
Tohle funguje v Haskellu, předpokládám, že do Elmu to půjde převést poměrně snadno (odstranil jsem haskelloviny..). Moc jsem to netestoval....
input :: [(Int, String)]
input = [(0, "- polozka1"), (1, "- polozka2"), (2, "- polozka3"), (1, "- polozka4")]
data Node = Node {
text :: String,
children :: [Node]
} deriving (Show)
genTree :: [(Int, String)] -> [Node]
genTree = map snd . foldr merge [] . map (\(lvl,txt) -> (lvl, Node txt []))
where
merge (l, left) [] = [(l, left)]
merge (l, left) acc@((r,_):_)
| l >= r = (l,left):acc
| otherwise =
let (childs,siblings) = span (\(lvl,_) -> lvl > l) acc
in (l, Node (text left) (map snd childs)) : siblings