kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

与えられた木から,子→親への対応を作る,を Scalaで書いてみた(XML版)

ScalaにはXMLリテラルがあるので、せっかくなのでXMLを使ったプログラムも書いてみた。XMLのNodeクラスには、子孫ノードを列挙してくれるメソッドがあるので、明示的に再帰を書かずに済んでいるが、XMLリテラルによって木構造を表現しているため、木構造を構築する部分が冗長になっている。

import scala.xml._
val tree = <Root>
  <Spine>
    <Neck><Head/></Neck>
    <RClavicle>
      <RUpperArm><RLowerArm><RHand/></RLowerArm></RUpperArm>
    </RClavicle>
    <LClavicle>
      <LUpperArm><LLowerArm><LHand/></LLowerArm></LUpperArm>
    </LClavicle>
  </Spine>
  <RHip>
    <RUpperLeg><RLowerLeg><RFoot/></RLowerLeg></RUpperLeg>
  </RHip>
  <LHip>
    <LUpperLeg><LLowerLeg><LFoot/></LLowerLeg></LUpperLeg>
  </LHip>
</Root>
val assocList = (tree \\ "_").flatMap{p => 
  p.child.filter{_.isInstanceOf[Elem]}.map{c => (Symbol(c.label), Symbol(p.label))}
}.toList
assocList.foreach(println)

実行結果。

('Spine,'Root)
('RHip,'Root)
('LHip,'Root)
('Neck,'Spine)
('RClavicle,'Spine)
('LClavicle,'Spine)
('Head,'Neck)
('RUpperArm,'RClavicle)
('RLowerArm,'RUpperArm)
('RHand,'RLowerArm)
('LUpperArm,'LClavicle)
('LLowerArm,'LUpperArm)
('LHand,'LLowerArm)
('RUpperLeg,'RHip)
('RLowerLeg,'RUpperLeg)
('RFoot,'RLowerLeg)
('LUpperLeg,'LHip)
('LLowerLeg,'LUpperLeg)
('LFoot,'LLowerLeg)