[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 - Smalltalk

Squeak Smalltalk で。

mamamoto さんの #4473 に感じ入ったあとでは、#groupBy:having: を便利に使っているつもりが使われてしまっているみたいでダメダメですね(^_^;)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| genTree printTree pathList tree |
genTree := [:paths |
    | leaf |
    leaf := paths groupBy: [:path | path first] having: [:g | true].
    leaf associationsDo: [:assoc |
        | newValue |
        newValue := assoc value
            collect: [:val | val allButFirst] thenSelect: [:val | val notEmpty].
        assoc value: (newValue isEmpty
            ifTrue: [newValue]
            ifFalse: [genTree copy fixTemps value: newValue])]].

printTree := [:dic :lev |
    dic keys asSortedCollection do: [:key |
        Transcript crtab: lev; show: key.
        (dic at: key) ifNotEmptyDo: [:child |
            printTree copy fixTemps value: child value: lev + 1]]].

pathList := #('abc\def' 'abc\def\gh' 'abc\def\ij' 'abc\jk\lm' 'de').
pathList := pathList collect: [:each | each subStrings: {$\}].

World findATranscript: nil.
tree := genTree copy fixTemps value: pathList.
printTree copy fixTemps value: tree value: 0

"=>
abc
    def
        gh
        ij
    jk
        lm
de
"

これはすばらしい!

感動したので、Squeak Smalltalk に意訳させていただきました。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| pathList tree dumpTree |
pathList := #('abc\def' 'abc\def\gh' 'abc\def\ij' 'abc\jk\lm' 'de').

tree := Dictionary new.
pathList do: [:path |
    (path subStrings: #($\)) inject: tree into: [:tr :dir |
        tr at: dir ifAbsentPut: [Dictionary new]]].

dumpTree := [:tr :lev |
    tr keys asSortedCollection do: [:key |
        Transcript crtab: lev; show: key.
        (tr at: key) ifNotEmptyDo: [:child |
            dumpTree copy fixTemps value: child value: lev + 1]]].

World findATranscript: nil.
dumpTree copy fixTemps value: tree value: 0

"=>
abc
    def
        gh
        ij
    jk
        lm
de
"

Index

Feed

Other

Link

Pathtraq

loading...