2016-09-19 7 views
1

次は私のADTです。注目すべき主なものは、パターンマッチングと再帰の問題

trait Cda { 
    def format: String = this match { 
    case f: Field => f.value 
    case Block(fields, children) => fields.map(f => f.format).mkString("|") + "|" + children.map(b => b.format).mkString("|") 
    case Record(keys, blocks) => blocks.map(b => b.format).mkString("|") 
    } 
} 

trait Field extends Cda { 
    val name: String 
    val value: String 
} 

case class StringField(name: String, value: String) extends Field 
case class DateField(name: String, value: String) extends Field 
case class TimeField(name: String, value: String) extends Field 
case class MatchKey(keyFields: Seq[Field]) extends Cda 
case class Block(fields: Seq[Field], children: Seq[Block] = Seq()) extends Cda 
case class Record(key: MatchKey, blocks: Seq[Block]) extends Cda 

childrenプロパティを見て(ブロックはネストすることができるということです続いているADT

//Block - AI 
val aiBlockId = StringField("blockId", "AI") 
val addlFieldPos = StringField("AdditionalFieldPosition", "addlFieldPos") 
val addlFieldName = StringField("AdditionalFieldName", "addlFieldName") 
val AI = Block(Seq(aiBlockId, addlFieldPos, addlFieldName)) 

//Block - RPS 
val rpsBlockId = StringField("blockId", "RPS") 
val dateOfStatus = DateField("DateOfStatus", "19240811") 
val timeOfStatus = TimeField("TimeOfStatus", "023829") 

val rpsBlocks = Seq(rpsBlockId, dateOfStatus, timeOfStatus) 

val rpsNestedBlocks = Seq(AI) 

val RPS = Block(rpsBlocks, rpsNestedBlocks) 

の例のインスタンスである私はRPS|19240811|023829|AI|addlFieldPos|addlFieldNameを返すようにフォーマットすることを期待していますが、私はRPS|19240811|023829|AI|addlFieldPos|addlFieldName|

再帰関数format(特にを変更する方法:最後に |追加のパイプを取得。)これを修正するには?

答えて

5

最初にseqsを組み合わせます。中間コレクションを作成しないイテレータを使用する方が安いです。ある

scala> val as = Seq(1,2,3) ; val bs = Seq.empty[Int] 
as: Seq[Int] = List(1, 2, 3) 
bs: Seq[Int] = List() 

scala> (as ++ bs).mkString("|") 
res0: String = 1|2|3 

scala> (as.iterator ++ bs).mkString("|") 
res1: String = 1|2|3 

case Block(fields, children) => (fields.iterator ++ children).map(_.format).mkString("|") 
3
trait Cda { 
    def format: String = this match { 
    case f: Field => f.value 
    case Block(fields, children) => fields.map(f => f.format).mkString("|") + {if (!children.isEmpty) {"|" + children.map(b => b.format).mkString("|")} else ""} 
    case Record(keys, blocks) => blocks.map(b => b.format).mkString("|") 
    } 
}