2016-10-01 45 views
0

案例1:鉴于串阶置字符串有条件

val l =List("@description", "AC", "T", "G", "+", "ZZZZ") 

什么来连接"AC", "T", "G"的好办法Scala的名单,该预期的结果

List("@description", "ACTG", "+", "ZZZZ") 

的规则是,从第二个元素开始,所有字符串应该连接,直到它碰到以+开头的另一个字符串。这与FASTQ格式解析有关,因为可以封装序列行。该功能预计将起作用(又称纯粹)。我认为这可能与foldLeft一起实施。

更新:谢谢你的回答!但我也意识到问题有点复杂,在下列情况下也应努力

情况2,输入:

val l = List("@desc", "AA", "T", "+foo", "XX", "X", "@desc2", "TT", "C", "+bar", "Y", "YY") 

预期输出:

List("@desc", "AAT", "+foo", "XXX", "@desc2", "TTC", "+bar", "YYY") 

所以可以有多个FASTQ记录在列表中。在上面的情况下,有两个。说明行必须以@开头。

CASE3

输入:

val l = List("@desc", "AAA", "TTT", "+foo", "@desc", "X", "@desc2", "TT", "C", "+bar", "+", "YY") 

预期输出:

List("@desc", "AAATTT", "+foo", "@descX", "@desc2", "TTC", "+bar", "+YY") 

这是三个品质自行的最具挑战性的情况下(即,第一后线以“+”开头的行)也可以以@+开头。例如“@desc”实际上是质量的一部分,而不是其他记录的起始行。区分描述和质量线的方法可能是序列线的长度和质量线的长度必须匹配。在第三种情况下,例如"AAATTT".length === "@descX".length,也"TTC".length == "+YY".length

+0

在案例3,质疑线条总是出现在2段? – Qingwei

+0

还有多少字符串用'+'在新行之前预期? – Qingwei

回答

1

它当然可以用foldLeft完成,但我认为可能会比以下更复杂。

def limitedConcat(ss: List[String]): List[String] = { 
    val idx = ss.indexWhere(_.startsWith("+")) 
    if (idx < 2) ss 
    else ss.head :: ss.slice(1, idx).mkString :: ss.drop(idx) 
} 

如果列表为空这应该工作,如果没有"+"元素,并且如果由于某种原因,"+"元素出现得太早。

1
val l = List("@description", "AC", "T", "G", "+", "ZZZZ") 
    val (prefix, suffix) = l.tail span (!_.startsWith("+")) 
    val result = l.head :: prefix.mkString :: suffix 
1

只是想补充一点,使用经常被遗忘span功能,这也是相当有效的答案。

def conditionalConcat(strings: List[String]): List[String] = strings match { 
    case Nil => Nil 
    case head :: tail => head :: { 
    val (beforePlus, afterPlus) = tail.span(!_.startsWith("+")) 
    beforePlus.mkString :: afterPlus 
    } 
} 

你可以尝试一下在ScalaFiddle

+0

'+:'和'::'有什么区别?阅读[doc](http://www.scala-lang.org/api/current/#scala.collection.immutable.List) – zyxue

+0

后,我仍然无法确定'+:'是一种可供所有人使用的方法'SeqLike'对象,而'::'特定于'List'。两者都是prepend,但使用'::'应该保证O(1)的复杂性,而'+:'不会。这很有帮助,因为当你重构时,你想知道是否有机会失去这种保证。 – lloydmeta

1

试试这个:

list.span(!_.startsWith("+")) match { 
    case (x::xs, rest) => x :: xs.mkString :: rest 
    case (_, rest) => rest 
} 
+0

你能解释一下第二种情况吗? – zyxue

+1

第二种情况下,当列表左侧部分为空时,所以它的模式与x :: xs不匹配。没有第二部分,对于空列表是不安全的 – Nyavro

0

我做到了对所有三种情况有以下两种功能工作思路我认为他们可以正常重构看起来更好

def extractQual(input: List[String], seqLength: Int, qual: String = ""): (String, List[String]) = { 
    if (qual.length == seqLength) (qual, input) 
    else if (qual.length > seqLength) ("", List()) 
    else extractQual(input.tail, seqLength, input.head + qual) 
    } 

def cleanFastqLines(lines: List[String], result: List[String] = List()): List[String] = lines match { 
    case desc :: Nil => Nil 
    case desc :: tail => { 
     val (beforePlus, rest) = tail.span(_.head != '+') 
     val seq = beforePlus.mkString 
     val altDesc = rest.head 
     val (qual, remained) = extractQual(rest.tail, seq.length) 
     if (remained.nonEmpty) List(desc, seq, altDesc, qual) ::: cleanFastqLines(remained, result) ::: result 
     else List(desc, seq, altDesc, qual) ::: result 
    } 
    }