2014-11-08 23 views
5

Cách tốt nhất để thêm Option vào số List là gì.Cách thêm Tùy chọn vào Danh sách

Đây là lần thử đầu tiên của tôi:

def append[A](as: List[A], maybeA1 : Option[A], maybeA2: Option[A]) : List[A] = as ++ maybeA1.toList ++ maybeA2.toList 

Côn: nó tạo ra 2 tmp List

(Tôi biết ToList() là không bắt buộc bởi vì có một chuyển đổi ngầm từ Tùy chọn [A] để Iterable [A])

thử khác là

def append2[A](ls: List[A], maybeA : Option[A]) : List[A] = maybeA.map(_ :: ls).getOrElse(ls) 
def append[A](as: List[A], maybeA1 : Option[A], maybeA2: Option[A]) : List[A] = append2(append2(as, maybeA1), maybeA2) 

Better mỗi f nhưng ít có thể đọc được…

Có cách nào khác không?

+1

Tại sao bạn muốn thêm tùy chọn [A] vào danh sách [A]. Chắc chắn bạn muốn xem liệu có cái gì đó đáng giá? –

+1

Không thêm vào cuối danh sách. – ziggystar

+2

Vâng, tôi ghét là anh chàng đó trên Stack Overflow, nhưng nếu bạn đang tìm kiếm chính mình để kết thúc, nó có giá trị yêu cầu: Có thực sự là một lý do bạn đang sử dụng 'List' ở đây (chứ không phải là một số loại khác của chuỗi)? –

Trả lời

5
def combine[A](s: Seq[A], o: Option[A]) = (s /: o)(_ :+ _) 
def combineAll[A](s: Seq[A], os: Option[A]*) = (s /: os)(combine) 

combineAll(List(1), Some(2), None, Some(3)) 
//res0: Seq[Int] = List(1, 2, 3) 
+2

Hoặc, cho ngắn gọn: '(s /: os) ((l, o) => o.fold (l) (l: + _))' –

+0

@BenReich cảm ơn, tôi đặt ý tưởng trong đó. Nó có thể trông giống như một ảo thuật –

1

Bạn có thể sử dụng danh sách người xây dựng có thể thay đổi

val builder = scala.collection.mutable.ListBuffer.empty[A] 
builder ++= list 
builder ++= maybe1 
builder ++= maybe2 
... 
builder.result() 

Nó có thể cung cấp những cải tiến hiệu suất nếu bạn có rất nhiều tùy chọn để thêm, gần gũi hơn với hàng ngàn, tôi nghĩ về số nhỏ hơn giải pháp ban đầu nên được tốt

-2
  1. Bạn không thể thêm Option[A] vào List[A]. Bạn phải sử dụng List[Option[A]] và sau đó thêm một tùy chọn là khá tầm thường, hoặc cho mọi tùy chọn bạn phải kiểm tra xem nó có thực sự giữ gì đó không (Some(a: A)) và thêm nó vào danh sách chỉ sau đó.
  2. Nếu thứ tự của các phần tử trong danh sách không phải là rất quan trọng, ít nhất là không phải trong giai đoạn thêm, thì tốt nhất là thêm chúng vào đầu, thay vì kết thúc, sử dụng toán tử ::. Việc thêm các phần tử vào đầu danh sách sẽ mất thời gian không đổi. Thêm chúng vào cuối có O (n) trong đó n là số phần tử đã có trong danh sách. Đó là bởi vì chương trình phải đi qua toàn bộ danh sách từ đầu đến cuối và chỉ sau đó mới có thể thêm phần tử mới.

Vì vậy, câu trả lời cho câu hỏi của bạn sẽ được một trong hai:

def add[A](ls: List[Option[A]], maybeA : Option[A]) = maybeA :: ls 

hoặc

def add[A](ls: List[A], maybeA : Option[A]) = maybeA match { 
    case Some(a) => a :: ls 
    case None => ls 
} 

Và sau đó, sau khi thêm tất cả các yếu tố mà bạn thích, bạn có thể chỉ cần gọi ls.reverse có họ theo thứ tự bạn sẽ có nếu bạn đang phụ thêm chúng.

+0

Có, bạn có thể thêm 'Tùy chọn [A]' vào 'Danh sách [A] '. Chỉ cần kích hoạt một REPL và dán mã này: 'List (1,2,3) ++ None ++ Một số (4) ++ Một số (5) ++ None' Điều này hoạt động chính xác giống như giải pháp thứ hai của bạn, nhưng đẹp hơn nhiều. Cũng gọi 'ls.reverse' sẽ đảo ngược danh sách ban đầu của bạn cũng không được dự định. –

+0

Cảm ơn bạn đã sửa lỗi đó với 'case None => ls'. Nhưng. 1. Tác giả không nói gì về ngữ cảnh. Đó là lý do tại sao tôi lần đầu tiên viết "nếu thứ tự không quan trọng", bởi vì có lẽ nó không phải là và chúng tôi có thể sử dụng '::' đó là nhanh hơn. Bên cạnh đó, điều này thêm một tùy chọn để liệt kê với '++' ... tốt, nó không thực sự thêm một ** tùy chọn **. Nó thêm ** A ** hoặc không có gì :) – makingthematrix

+0

1. Một 'List' theo định nghĩa được sắp xếp, do đó, cung cấp một giải pháp làm rối trật tự, trong cuốn sách của tôi, không chính xác. 2. Câu hỏi cung cấp hai ví dụ về ý nghĩa của tác giả về việc "thêm một tùy chọn vào danh sách" và nếu bạn đã thử chúng, bạn có thể thấy rằng chúng thực sự là "thêm A hoặc không có gì". –

Các vấn đề liên quan