2012-03-04 35 views
35

Tôi đang cố gắng tìm kiếm bộ sưu tập scala cho một mục trong danh sách khớp với một số biến vị ngữ. Tôi không nhất thiết cần giá trị trả lại, chỉ cần kiểm tra nếu danh sách chứa nó.Tìm một mục phù hợp với vị ngữ trong Scala

Trong Java, tôi có thể làm điều gì đó như:

for (Object item : collection) { 
    if (condition1(item) && condition2(item)) { 
     return true; 
    } 
} 
return false; 

Trong Groovy, tôi có thể làm điều gì đó như:

return collection.find { condition1(it) && condition2(it) } != null 

cách thành ngữ để làm điều này trong Scala là gì? Tất nhiên tôi có thể chuyển đổi kiểu vòng lặp Java thành Scala, nhưng tôi cảm thấy như có một cách chức năng hơn để làm điều này.

+0

Tôi sẽ không lo lắng quá nhiều về tính tự nhiên hoặc chức năng: các bộ sưu tập trong thư viện Scala có phương thức 'exist' và' find' (sự khác biệt là 'find' trả về phần tử). như phần tử được tìm thấy. Cả hai đều được thực hiện với một vòng lặp 'var' và' while', trông rất giống với việc thực hiện java mà bạn có (ngoại trừ việc dùng biến vị ngữ làm tham số). – herman

Trả lời

42

Sử dụng bộ lọc:

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

// take only that values that both are even and greater than 3 
scala> collection.filter(x => (x % 2 == 0) && (x > 3)) 
res1: List[Int] = List(4) 

// you can return this in order to check that there such values 
scala> res1.isEmpty 
res2: Boolean = false 

// now query for elements that definitely not in collection 
scala> collection.filter(x => (x % 2 == 0) && (x > 5)) 
res3: List[Int] = List() 

scala> res3.isEmpty 
res4: Boolean = true 

Nhưng nếu tất cả bạn cần là để kiểm tra sử dụng exists:

scala> collection.exists(x => x % 2 == 0) 
res6: Boolean = true 
+0

Đúng, trông giống như phương pháp tôi đang tìm kiếm. Vẫn học Scala ... Cảm ơn. –

+7

Bộ sưu tập đơn giản hơn một chút {x => điều kiện1 (x) && điều kiện2 (x)} ' – 4e6

+0

@Yep, tôi đã thêm cái này quá –

48

Kiểm tra nếu phù hợp với giá trị ngữ tồn tại

Nếu bạn chỉ quan tâm đến việc thử nghiệm nếu có giá trị, bạn có thể làm điều đó với .... exists

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

scala> l exists (_>5) 
res1: Boolean = false 

scala> l exists (_<2) 
res2: Boolean = true 

scala> l exists (a => a<2 || a>5) 
res3: Boolean = true 

Các phương pháp khác (một số dựa trên ý kiến):

yếu tố phù hợp Đếm

yếu tố Đếm đáp ứng vị (và kiểm tra nếu count> 0)

scala> (l count (_ < 3)) > 0 
res4: Boolean = true 

Trở đầu tiên yếu tố phù hợp

Tìm phần tử đầu tiên thỏa mãn vị ngữ (như đề xuất của Tomer Gabel và Luigi Plinge, điều này sẽ hiệu quả hơn vì nó trả về ngay khi nó kết thúc ds một yếu tố thỏa mãn vị, chứ không phải đi qua toàn bộ Danh sách nào)

scala> l find (_ < 3) 
res5: Option[Int] = Some(1) 

// also see if we found some element by 
// checking if the returned Option has a value in it 
scala> l.find(_ < 3) isDefined 
res6: Boolean = true 

Kiểm tra nếu giá trị chính xác tồn tại

Đối với trường hợp đơn giản mà chúng tôi đang thực sự chỉ kiểm tra nếu một yếu tố cụ thể là trong danh sách

scala> l contains 2 
res7: Boolean = true 
+1

Nếu bạn * là * quan tâm đến giá trị trả về, sử dụng findFirst. Bạn cũng có thể nhận được số lượng bằng cách sử dụng chức năng tự đặt tên. Tất cả đều có cùng vị từ. –

+3

Đó là 'find', không phải' findFirst', nhưng có hiệu quả hơn việc lọc toàn bộ danh sách –

+0

@LuigiPlinge Tôi đã thêm đề xuất của Tomer với sửa chữa của bạn. Cảm ơn! –

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