2016-08-12 43 views
-1

我想在Swift中的CollectionType上編寫一個擴展,它將在數組中的對象之後找到x對象。顯然,即使物品後面沒有物品,也需要保護它才能正常工作。擴展Swift中的集合類型以查找對象之後的所有對象

在我腦海中的簽名是這樣的:

func itemsAfterItem(item: T, limit: Int?) -> [T] 

我無法弄清楚如何,雖然實現它,可能有人幫助嗎?

+1

你有沒有嘗試過除了簽名以外的任何東西? – luk2302

回答

3

Equatable元素(解釋內聯)的任意集合的可能實現。主要的挑戰是獲得正確的參數類型和約束。

extension CollectionType where Generator.Element: Equatable, 
         SubSequence.Generator.Element == Generator.Element { 

    func itemsAfterItem(item: Generator.Element, limit: Index.Distance?) -> [Generator.Element] { 
     if let idx = indexOf(item) where idx != endIndex { 
      // Start after the given item: 
      let from = idx.advancedBy(1) 
      // Up to min(from + limit, endIndex): 
      let to = limit.map { from.advancedBy($0, limit: endIndex) } ?? endIndex 
      // Return slice as an array: 
      return Array(self[from..<to]) 
     } else { 
      // Item not found, or only at the last position. 
      return [] 
     } 
    } 
} 

瞭解

let to = limit.map { from.advancedBy($0, limit: endIndex) } ?? endIndex 

部分留給讀者作爲練習向讀者:)

實例:

[1, 2, 3, 4, 5, 6].itemsAfterItem(2, limit: 2) // [3, 4] 
["x", "y", "z"].itemsAfterItem("y", limit: 4)  // ["z"] 
[1, 2, 3].itemsAfterItem(7, limit: 4)    // [] 
[1.1, 2.2, 3.3].itemsAfterItem(1.1, limit: nil) // [2.2, 3.3] 

實施例用於非數組集合:

"abcdef".characters.itemsAfterItem("b", limit: 2) // ["c", "d"] 
0

我想你可以試試這個:

func itemsAfterItem(item: T, limit: Int?) -> [T] { 
    var counter: Int = 0 
    var isAfter: Bool = false 
    let array = [T]() 
    let newLimit = limit != nil ? limit : myArray.count 
    for tmpItem in myArray { 
     if tmpItem == T { 
      isAfter = true 
     } 
     if isAfter && counter < limit { 
      array.append(tmpItem) 
      counter += 1 
     } 
    } 
} 

此功能將使您的T項目在數組的開始。

我沒有測試這個功能

2

只是因爲我喜歡挑戰;)

extension Array where Element : Equatable { 
    func itemsAfterItem(item: Element, limit: Int? = nil) -> [Element] { 
     if let from = self.indexOf(item) where from < self.count - 1 { 
      if let limit = limit where from + limit < self.count { 
       return Array(self[from+1...from + limit]) 
      } 
      return Array(self[from+1...self.count-1]) 
     } else { 
      return [] 
     } 
    } 
} 

對於輸入

let arr = [1, 2, 4, 6, 9] 

它導致

arr.itemsAfterItem(2)    // [4, 6, 9] 
arr.itemsAfterItem(2, limit: 2) // [4, 6] 
arr.itemsAfterItem(2, limit: 100) // [4, 6, 9] 
arr.itemsAfterItem(9, limit: 2) // [] 
arr.itemsAfterItem(3, limit: 100) // [] 
+0

我想我們基本上有同樣的想法:) - 請注意'Equatable'已經足夠了,你可以簡化爲'let index = self.indexOf(item)'。 –

+0

@MartinR謝謝!你的解決方案看起來更清潔一些......我的swift是一個生鏽的小人,由於所有的正常工作和所有的口袋妖怪都去了相關的東西,所以無法編程很多:P – luk2302