2016-05-24 15 views
6

Trong Swift làm thế nào tôi có thể kiểm tra xem một mảng có chứa một subarray nhất định trong toàn bộ? Ví dụ, có một chức năng contains mà làm việc như thế này:Mảng có chứa một subarray hoàn chỉnh

let mainArray = ["hello", "world", "it's", "a", "beautiful", "day"] 
contains(mainArray, ["world", "it's"]) // would return true 
contains(mainArray, ["world", "it"]) // would return false 
contains(mainArray, ["world", "a"]) // would return false - not adjacent in mainArray 

Trả lời

3

Bạn có thể làm điều đó với chức năng cấp cao hơn, như thế này:

func indexOf(data:[String], _ part:[String]) -> Int? { 
    // This is to prevent construction of a range from zero to negative 
    if part.count > data.count { 
     return nil 
    } 

    // The index of the match could not exceed data.count-part.count 
    return (0...data.count-part.count).indexOf {ind in 
     // Construct a sub-array from current index, 
     // and compare its content to what we are looking for. 
     [String](data[ind..<ind+part.count]) == part 
    } 
} 

hàm này trả về chỉ số của các trận đấu đầu tiên, nếu có, hoặc nil otherwi se.

Bạn có thể sử dụng nó như sau:

let mainArray = ["hello", "world", "it's", "a", "beautiful", "day"] 
if let index = indexOf(mainArray, ["world", "it's"]) { 
    print("Found match at \(index)") 
} else { 
    print("No match") 
} 

Editing nhập như một phần mở rộng cho một mảng chung ...

này bây giờ có thể được sử dụng cho bất kỳ mảng đồng nhất của Equatable loại.

extension Array where Element : Equatable { 
    func indexOfContiguous(subArray:[Element]) -> Int? { 

     // This is to prevent construction of a range from zero to negative 
     if subArray.count > self.count { 
      return nil 
     } 

     // The index of the match could not exceed data.count-part.count 
     return (0...self.count-subArray.count).indexOf { ind in 
      // Construct a sub-array from current index, 
      // and compare its content to what we are looking for. 
      [Element](self[ind..<ind+subArray.count]) == subArray 
     } 
    } 
} 
+0

Tôi nghĩ rằng điều này sẽ làm việc nhưng có thể là quá thông minh cho mọi người hiểu. (Nó chắc chắn là dành cho tôi). Có thể bạn có thể thêm một số ý kiến ​​cho điều này để giải thích những gì nó đang làm? – Fogmeister

+0

@Fogmeister Chắc chắn! Tuy nhiên, điều này ít đáng sợ hơn vẻ bề ngoài, về cơ bản, "reduce" thay thế một vòng lặp "for" trên chỉ mục ban đầu, trong khi '[String] (dữ liệu [ind .. dasblinkenlight

+0

OK, do đó, về cơ bản nó ... bắt đầu tại 0. Kiểm tra subarray tại 0 bằng tham số 'part'. Nếu nó được trả về 0 tất cả các cách thức thông qua. Nếu nó không phải là đi đến 1 và kiểm tra subarray tại 1 là bằng tham số phần và như vậy? – Fogmeister

-2

Mảng không có khả năng sẵn có mà bạn đang tìm kiếm, tuy nhiên bạn có thể sử dụng bộ được thiết kế để xử lý các tình huống như vậy ..

let mainSet:Set = ["hello", "world", "it's", "a", "beautiful", "day"] 
let list2:Set = ["world", "it's"] 
let list3:Set = ["world","a"] 
list2.isSubsetOf(mainSet) 
+3

Cách tiếp cận của bạn sẽ đánh giá sai '[" thế giới "," a "]' như là một "lớp con". –

+0

Có, tất nhiên, để đáp ứng điều kiện đó có lẽ chúng ta có thể cần phải sử dụng vị từ tùy chỉnh ... – chitnisprasanna

+0

@chitnisprasanna Ý của bạn là gì? Bạn đang nói "OK giải pháp của tôi không hoạt động, tôi sẽ phải chương trình này"? Làm thế nào bạn sẽ giải quyết điều này? – Daniel

2

Theo như tôi biết, chức năng như vậy không tồn tại. Nhưng bạn có thể thêm các chức năng với phần mở rộng sau:

extension Array where Element: Equatable { 
    func contains(subarray: [Element]) -> Bool { 
     var found = 0 
     for element in self where found < subarray.count { 
      if element == subarray[found] { 
       found += 1 
      } else { 
       found = element == subarray[0] ? 1 : 0 
      } 
     } 

     return found == subarray.count 
    } 
} 

Khi phần mở rộng được thêm vào dự án của bạn, bạn chỉ có thể gọi:

mainArray.contains(["world", "it's"]) // would return true 
mainArray.contains(["world", "it"]) // would return false 
mainArray.contains(["it's", "world"]) // would return false 

let array2 = ["hello", "hello", "world"] 
array2.contains(["hello", "world"]) // would return true 
0

nỗ lực đầu tiên simpleBob dường như làm việc với một sửa đổi tối thiểu:

extension Array where Element: Equatable { 
    func contains(subarray: [Element]) -> Index? { 
     var found = 0 
     var startIndex:Index = 0 
     for (index, element) in self.enumerate() where found < subarray.count { 
      if element != subarray[found] { 
       found = 0 
      } 
      if element == subarray[found] { 
       if found == 0 { startIndex = index } 
       found += 1 
      } 
     } 

     return found == subarray.count ? startIndex : nil 
    } 
} 
Các vấn đề liên quan