[topic] フォルダパス一覧のツリー構造への変換

(相対)フォルダのパスの一覧が与えられ、そのフォルダパスの一覧をツリー構造に変換してください。
フォルダパスの区切り文字は'\'文字を使用しています。

以下のような1行1パスのフォルダのパスがあった場合、
 abc\def
 abc\def\gh
 abc\def\ij
 abc\jk\lm
 de

イメージとして、以下のようなツリー構造を構築できればOKです。
 ROOT
 ┗abc
  ┗def
   ┗gh
   ┗ij
  ┗jk
   ┗lm
 ┗de

ツリーですのでルートがあります。上記のフォルダ一覧はルート以下にぶら下げてください。また、同じフォルダにぶら下がっているサブフォルダの名前は重複させてはいけません。

上記のような出力は結果の分かりやすさとしてあった方がいいですが、なければないで構いません。また、ASやJavaFXでグラフィカルな結果を表示するプログラムでも構いませんが、データ構造はちゃんと作ってください。

Posted feedbacks - Haskell

ファイルパスの分解には,System.FilePath.Windows モジュールの splitPath
を用いる.Unix系ファイルシステム流の'/'の場合は System.FilePath.Unixを
用いればよい.

ツリーの構築と表示には Data.Tree モジュール unfoldTree および drawTree
をそれぞれ用いる.

実行例:
*Main> putStrLn $ drawTree $ buildFS pathList
ROOT
|
+- abc
|  |
|  +- def
|  |  |
|  |  +- gh
|  |  |
|  |  `- ij
|  |
|  `- jk
|     |
|     `- lm
|
`- de
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import Data.List
import Data.Tree
import System.FilePath.Windows

binapp o f x y = f x `o` f y

type FS = Tree FilePath

buildFS :: [String] -> FS
buildFS = Node "ROOT" . map buildDir . groupPath . map splitPath . sort

buildDir :: (FilePath,[[FilePath]]) -> FS
buildDir = unfoldTree phi
 where phi (n,ps) = (delete pathSeparator n, groupPath $ filter (not . null) ps)

groupPath :: [[FilePath]] -> [(FilePath,[[FilePath]])]
groupPath = map grouping . groupBy (binapp eqpath head)
  where grouping ss = (head . head $ ss, map tail ss)
        eqpath      = binapp (==) (fst . break (pathSeparator==))

pathList = ["abc\\def","abc\\def\\gh","abc\\def\\ij","abc\\jk\\lm","de"]

Index

Feed

Other

Link

Pathtraq

loading...