簡體   English   中英

Scala遍歷列表

[英]Scala iterate over list

如何在不使用可變集合的情況下將List(1,2,30,13,4)轉換為List(1,2,3,4)

30是一種轉義號碼; 如果找到,應將其刪除,下一個數字應減少10。

無論如何,您可能應該檢查您的代碼/用例,因為有點類似:

List(1,2,30,13,4).foldLeft((List.empty[Int], false)) {
  case ((accumulator, wasFound), next) =>
    if(wasFound) (accumulator :+ (next - 10), false)
    else if(next == 30) (accumulator, true)
    else (accumulator :+ next, false)
}._1

基本上,您可以保留一個布爾值和一個累加器,並使用它來記住是否找到了30,並采取適當的措施以防萬一。

請注意,如果您有類似List(1,3,30,40)的輸出,這將對您沒有幫助,輸出將是List(1,3,30) ,您應該弄清楚這種情況是否可以接受,如果不,我將使用一個遞歸解決方案,該解決方案允許在元素為30的情況下對元素進行兩次迭代:

scala> def loop(list: List[Int], acc: List[Int], wasFound: Boolean, toRemove: Int): List[Int] = list match {
 |     case h :: t =>
 |       if(wasFound) loop((h - 10) :: t, acc, false, toRemove)
 |       else if(h == toRemove) loop(t, acc, true, toRemove)
 |       else loop(t, acc :+ h, false, toRemove)
 |     case Nil =>
 |       acc
 |   }
loop: (list: List[Int], acc: List[Int], wasFound: Boolean, toRemove: Int)List[Int]

scala> loop(List(1,2,30,13,4), List(), false, 30)
res1: List[Int] = List(1, 2, 3, 4)

scala> loop(List(1,2,30,40, 13,4), List(), false, 30)
res2: List[Int] = List(1, 2, 3, 4)

邏輯非常相似,唯一的不同是您對30之后的那個進行了兩次迭代,因此,如果它又是30,則將其刪除並減少下一個。

將上一個項目壓縮到每個項目,然后使用collect和部分函數確定是否返回什么:

l.zip(l.head :: l).collect {
  case (v, 30) if v != 30 => v - 10  // only previous is 30 - decrease 10
  case (v, prev) if v != 30 => v     // none of them is 30 - just return value
  // skipping (filtering out) case where v == 30
}

例如:

  • 對於val l = List(1,2,30,13,4,30,15,6) ,這將返回List(1,2,3,4,5,6)
  • 對於val l = List(1,3,30,40) ,返回List(1,3,30)
  • 對於val l = List(30,11,2) ,返回List(1,2)

遵循@Victor注釋並概括:

def escapeAdjust[A](xs: List[A], p: A => Boolean, f: A => A): List[A] = {
  @tailrec
  def loop(ys: List[A], p: A => Boolean, f: A => A, acc: List[A]): List[A] = ys match {
    case Nil => acc
    case h :: Nil => if (p(h)) acc else h :: acc
    case h :: next :: rest => if (p(h)) loop(f(next) :: rest, p, f, acc)
                              else loop(next :: rest, p, f, h :: acc)
  }
  loop(xs, p, f, List[A]()).reverse
}

用法:

val p = (x: Int) => x == 30
val f = (y: Int) => y - 10

escapeAdjust(List[Int](1,2,30,13,4), p, f)
res12: List[Int] = List(1, 2, 3, 4)

escapeAdjust(List(1,2,30,13,4,30,15,6), p, f)
res13: List[Int] = List(1, 2, 3, 4, 5, 6)

escapeAdjust(List(1,3,30,40), p, f)
res14: List[Int] = List(1, 3)

escapeAdjust(List(30,11,2), p, f)
res15: List[Int] = List(1, 2)

escapeAdjust(List(1,3,30,40, 5), p, f)
res16: List[Int] = List(1, 3, -5)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM