13

結果のリストに Scala で交互に 2 つのリストの要素が含まれるように、2 つのリストをマージするにはどうすればよいですか。

入力:

val list1 = List("Mary", "a", "lamb")

val list2 = List("had", "little")

出力:

List("Mary", "had", "a", "little", "lamb")
4

4 に答える 4

21

あなたが探しているものは、通常、「散在」または「インターカレート」と呼ばれ、それを行う方法がいくつかあります。

def intersperse[A](a : List[A], b : List[A]): List[A] = a match {
  case first :: rest => first :: intersperse(b, rest)
  case _             => b
}

使用することもできますscalaz

import scalaz._
import Scalaz._

val lst1 = ...
val lst2 = ...

lst1 intercalate lst2

編集:次のこともできます:

lst1.zipAll(lst2,"","") flatMap { case (a, b) => Seq(a, b) }

考えてみると、明確でありながら最も簡潔であるため、最後の解決策が私のお気に入りだと思います。すでに Scalaz を使用している場合は、2 番目のソリューションを使用します。ただし、最初のものも非常に読みやすいです。

そして、この回答をより完全にするために、一般的な@Travis Brownのソリューションを追加します:

list1.map(List(_)).zipAll(list2.map(List(_)), Nil, Nil).flatMap(Function.tupled(_ ::: _))
于 2013-11-06T11:46:23.817 に答える
5
val list1 = List("Mary", "a", "lamb")
val list2 = List("had", "little")

def merge1(list1: List[String], list2: List[String]): List[String] = {
    if (list1.isEmpty) list2
    else list1.head :: merge(list2, list1.tail)
}

def merge2(list1: List[String], list2: List[String]): List[String] = list1 match {
    case List() => list2
    case head :: tail => head :: merge(list2, tail)
} 

merge1(list1, list2)
merge2(list1, list2)
//> List[String] = List(Mary, had, a, little, lamb)
于 2013-11-06T11:39:16.647 に答える
1
list1.zipAll(list2,"","").flatMap(_.productIterator.toList).filter(_ != "")
于 2013-11-06T11:45:16.830 に答える
1

次のようなことができます。

def alternate[A]( a: List[A], b: List[A] ): List[A] = {
    def first( a: List[A], b: List[A] ): List[A] = a match {
        case Nil => Nil
        case x :: xs => x :: second( xs, b )
    }

    def second( a: List[A], b: List[A] ): List[A] = b match {
        case Nil => Nil
        case y :: ys => y :: first( a, ys )
    }

    first( a, b )
}    
于 2013-11-06T11:46:11.237 に答える