Доступ к следующему элементу в списке для сравнения в Scala - PullRequest
11 голосов
/ 20 апреля 2011

Я новичок в Scala, и мне было интересно, как можно вызвать следующий элемент списка, потому что я пытаюсь сравнить текущий элемент с соседним.Учитывая х в качестве текущего элемента, я попытался аналогично Java, х + 1, но это не сработало.Любая помощь?

for (x <- list; if (x == (next adj. element))) println("same")

Ответы [ 8 ]

30 голосов
/ 20 апреля 2011

Как насчет скольжения?

val list = List(1,2,3,4)
list.sliding(2).foreach(println)

//List(1, 2)
//List(2, 3)
//List(3, 4)
7 голосов
/ 20 апреля 2011

Канонические способы сделать это в цикле for были бы:

scala> val xs = List(1,2,3,4,3,2)
xs: List[Int] = List(1, 2, 3, 4, 3, 2)

scala> for (List(left,right) <- xs.sliding(2) if (left < right)) println(left + " < " + right)
1 < 2
2 < 3
3 < 4

scala> for ((left,right) <- (xs zip xs.tail) if (left < right)) println(left + " < " + right)
1 < 2
2 < 3
3 < 4

(Кстати, в этом примере вам, вероятно, лучше поместить выражение if снаружи, а не внутри для понимания).)

Если у вас есть индексы вместо значений, вы просто разыменовываете их, используя тот же шаблон.Лично я не нахожу эту модель очень четкой или полезной.Это медленно, имеет странные угловые случаи со списками, которые не полны, и трудно следить за тем, что происходит.Вместо этого я определяю

class PairedIterable[A](it: Iterable[A]) {
  def foreachpair(f: (A,A) => Unit) = {
    val i = it.iterator
    if (i.hasNext) {
      var prev = i.next
      while (!ans && i.hasNext) {
        val x = i.next
        f(prev,x)
        prev = x
      }
    }
  }
}
implicit def iterable_has_pairs[A](it: Iterable[A]) = new PairedIterable(it)

, который затем можно использовать так:

scala> xs.foreachpair((left, right) => if (left < right) println(left + " < " + right))
1 < 2
2 < 3
3 < 4

Варианты "forallpair", "existpair" и "findpair" особенно полезны.

3 голосов
/ 21 апреля 2011

Это было бы лучше обработать путем повторения по списку вместо итерации по элементам , поскольку элементы ничего не знают о списке.

Например:

def recurse[T](list: List[T]): Unit = list match {
    case List(x, y, _*) if x == y => 
        println("same")
        recurse(list.tail)
    case Nil =>
    case _   => recurse(list.tail)
}
2 голосов
/ 20 апреля 2011
scala> val xs = 1::3::5::4::Nil
xs: List[Int] = List(1, 3, 5, 4)

scala> (xs, xs.tail).zip.foreach(println)
(1,3)
(3,5)
(5,4)

scala>
2 голосов
/ 20 апреля 2011

В качестве опции вы можете использовать match и рекурсию вместо for:

object Test {
  def main(args: Array[String]) {
    val list = List(1, 5, 3)
    loop(list)
  }

  def loop(list: List[Int]) {
    list match {
      case Nil => println("Empty list")
      case x :: Nil => println("last " + x)
      case x :: tail => {
        println(x + " - " + tail.head)
        loop(tail)
      }

    }
  }
}
0 голосов
/ 24 июля 2016

Как и в Scala 2.11.7, допустимо следующее:

scala> val xs = List(1,2,3,4)
xs: List[Int] = List(1, 2, 3, 4)

1) застегните хвост

scala> xs.zip(xs.tail)
res0: List[(Int, Int)] = List((1,2), (2,3), (3,4))

2) Сдвиньте окно

scala> xs.sliding(2)
res1: Iterator[List[Int]] = non-empty iterator
0 голосов
/ 20 августа 2013

list.tail.head

дает следующий элемент, если вы хотите просмотреть все элементы в начале списка. Это потому, что head - самый передний элемент, а tail - остальная часть списка.

0 голосов
/ 20 апреля 2011
scala> val li = List (3, 4, 5) 
li: List[Int] = List(3, 4, 5)

scala> li.tail.head 
res74: Int = 4
...