Làm cách nào để chia một chuỗi thành hai danh sách bằng một vị từ?
Thay thế: Tôi có thể sử dụng filter
và filterNot
hoặc viết phương thức của riêng mình, nhưng không có phương thức nào tốt hơn (tích hợp sẵn) tốt hơn?
Làm cách nào để chia một chuỗi thành hai danh sách bằng một vị từ?
Thay thế: Tôi có thể sử dụng filter
và filterNot
hoặc viết phương thức của riêng mình, nhưng không có phương thức nào tốt hơn (tích hợp sẵn) tốt hơn?
Câu trả lời:
Bằng cách sử dụng partition
phương pháp:
scala> List(1,2,3,4).partition(x => x % 2 == 0)
res0: (List[Int], List[Int]) = (List(2, 4),List(1, 3))
_ % 2 == 0
.
Tốt đó partition
là điều bạn muốn - có một phương pháp mà còn sử dụng một vị để chia một danh sách trong hai: span
.
Phân vùng đầu tiên sẽ đặt tất cả các phần tử "true" trong một danh sách và các phần tử khác trong danh sách thứ hai.
span sẽ đặt tất cả các phần tử trong một danh sách cho đến khi một phần tử là "false" (về mặt vị từ). Từ thời điểm đó trở đi, nó sẽ đưa các phần tử vào danh sách thứ hai.
scala> Seq(1,2,3,4).span(x => x % 2 == 0)
res0: (Seq[Int], Seq[Int]) = (List(),List(1, 2, 3, 4))
Bạn có thể muốn xem scalex.org - nó cho phép bạn tìm kiếm thư viện tiêu chuẩn của scala cho các hàm bằng chữ ký của chúng. Ví dụ: nhập như sau:
List[A] => (A => Boolean) => (List[A], List[A])
Bạn sẽ thấy phân vùng .
Bạn cũng có thể sử dụng foldLeft nếu cần thêm một chút gì đó. Tôi chỉ viết một số mã như thế này khi phân vùng không cắt nó:
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)
}
}
Tôi biết tôi có thể đến muộn bữa tiệc và có nhiều câu trả lời cụ thể hơn, nhưng bạn có thể tận dụng 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)
Điều này làm cho mã của bạn dễ kiểm chứng hơn trong tương lai nếu bạn cần thay đổi điều kiện thành một thứ gì đó không boolean.
Nếu bạn muốn chia danh sách thành nhiều hơn 2 phần và bỏ qua các giới hạn, bạn có thể sử dụng một cái gì đó như thế này (sửa đổi nếu bạn cần tìm kiếm các int)
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)
là một cách để hủy bộ dữ liệu kết quảpartition
theo cách có thể đọc được.