Bagaimana cara membagi urutan menjadi dua daftar dengan predikat?
Alternatif: Saya dapat menggunakan filter
dan filterNot
, atau menulis metode saya sendiri, tetapi bukankah ada metode yang lebih umum (bawaan) yang lebih baik?
Bagaimana cara membagi urutan menjadi dua daftar dengan predikat?
Alternatif: Saya dapat menggunakan filter
dan filterNot
, atau menulis metode saya sendiri, tetapi bukankah ada metode yang lebih umum (bawaan) yang lebih baik?
Jawaban:
Dengan menggunakan partition
metode:
scala> List(1,2,3,4).partition(x => x % 2 == 0)
res0: (List[Int], List[Int]) = (List(2, 4),List(1, 3))
_ % 2 == 0
.
Baik yang partition
adalah hal yang Anda inginkan - ada metode lain yang juga menggunakan predikat untuk membagi daftar di dua: span
.
Yang pertama, partisi akan meletakkan semua elemen "benar" dalam satu daftar, dan yang lainnya di daftar kedua.
span akan menempatkan semua elemen dalam satu daftar hingga elemen bernilai "false" (dalam istilah predikat). Sejak saat itu, ia akan menempatkan elemen-elemen tersebut dalam daftar kedua.
scala> Seq(1,2,3,4).span(x => x % 2 == 0)
res0: (Seq[Int], Seq[Int]) = (List(),List(1, 2, 3, 4))
Anda mungkin ingin melihat scalex.org - ini memungkinkan Anda untuk mencari pustaka standar scala untuk fungsi dengan tanda tangannya. Misalnya, ketikkan yang berikut ini:
List[A] => (A => Boolean) => (List[A], List[A])
Anda akan melihat partisi .
Anda juga dapat menggunakan foldLeft jika Anda membutuhkan sesuatu yang lebih. Saya baru saja menulis beberapa kode seperti ini ketika partisi tidak memotongnya:
val list:List[Person] = /* get your list */
val (students,teachers) =
list.foldLeft(List.empty[Student],List.empty[Teacher]) {
case ((acc1, acc2), p) => p match {
case s:Student => (s :: acc1, acc2)
case t:Teacher => (acc1, t :: acc2)
}
}
Saya tahu saya mungkin terlambat ke pesta dan ada jawaban yang lebih spesifik, tetapi Anda dapat memanfaatkannya groupBy
val ret = List(1,2,3,4).groupBy(x => x % 2 == 0)
ret: scala.collection.immutable.Map[Boolean,List[Int]] = Map(false -> List(1, 3), true -> List(2, 4))
ret(true)
res3: List[Int] = List(2, 4)
ret(false)
res4: List[Int] = List(1, 3)
Ini membuat kode Anda sedikit lebih tahan masa depan jika Anda perlu mengubah kondisi menjadi sesuatu yang bukan boolean.
Jika Anda ingin membagi daftar menjadi lebih dari 2 bagian, dan mengabaikan batasannya, Anda dapat menggunakan sesuatu seperti ini (ubah jika Anda perlu mencari ints)
def split(list_in: List[String], search: String): List[List[String]] = {
def split_helper(accum: List[List[String]], list_in2: List[String], search: String): List[List[String]] = {
val (h1, h2) = list_in2.span({x: String => x!= search})
val new_accum = accum :+ h1
if (h2.contains(search)) {
return split_helper(new_accum, h2.drop(1), search)
}
else {
return accum
}
}
return split_helper(List(), list_in, search)
}
// TEST
// split(List("a", "b", "c", "d", "c", "a"), {x: String => x != "x"})
val (even, odd) = List(1,2,3,4).partition(x => x % 2 == 0)
adalah cara untuk menghancurkan tupel yang dihasilkanpartition
dengan cara yang dapat dibaca.