2017-06-17 117 views
0

不工作,我承認有點感覺愚蠢,但試圖小時後我要問:陣列搜索功能斯威夫特

class AGE { 

    static func getAge() -> Int { 

     var age: Int 

     for items in dataArray { 
      if items.name == "Steven" { 
       age = items.age 
      } 

      else { 
       age = 0 
      } 
     } 

     // variable "age" used before being initialized - WHY? 
     return age 
    } 
} 

我甚至嘗試在一開始設定var age: Int = 0,但隨後的功能return 0。我希望有人能夠在這一點上原諒我這個基本問題。任何幫助讚賞。

爲了更清楚dataArray中的樣子:

struct Person { 
    let name: String 
    let lastName: String 
    let age: Int 
} 

let person1: Person = Person(name: "Steven", lastName: "miller", age: 23) 
let person2: Person = Person(name: "jana", lastName: "drexler", age: 31) 
let person3: Person = Person(name: "hanna", lastName: "montana", age: 56) 

var dataArray = [Person]() 

dataArray.append(person1) 
dataArray.append(person2) 
dataArray.append(person3) 

更新

試圖組裝所有答案的本質,解決方案必須是這樣的: 類AGE {

static func getAge() ->Int { 

     var age: Int = 0 

     for items in dataArray { 
      while items.firstName == "Steven" { 
       age = items.age 

       return age 

       break  // This break will never be executed because of return. 
      } 
      break   // setting the break here, the loop will break after first round 
     } 
     return age 
    } 
} 

此代碼工作,(與第二次休息),但只適用於第一個循環。剩下的問題是,在循環達到目標後如何設置返回和中斷。返回或中斷將阻止另一個步驟。

+0

什麼是'dataArray'? – paper1111

+0

根據您的確切用例,您可能需要考慮在'dataArray'爲空的情況下使'age'可選,返回'nil'。正如在這種情況下,答案是「年齡是多少?」可能不是「剛創建」,而是「沒有年齡」。 – Hamish

+0

現在我添加了dataArray。 –

回答

3

在返回之前導致age初始化的可能的程序流路徑並非詳盡無遺。在dataArray爲空的情況下,將永遠不會輸入for ... in循環的主體,並且age將永遠不會初始化。在您的特定示例中解決此問題的最簡單方法是在聲明後初始化age0

關於即使萬一dataArray的「意外」 0收益包含與name財產價值"Steven"的元素:在for ... in循環,它每次經過包含有name財產價值"Steven"的元素,你會age的值重置爲0。這意味着只有在"Steven"值元素是dataArray中的最後一個時,值纔會保持不變。我沒有看到任何理由在初始化之後再次將age設置爲0,因此您可以通過例如解決此問題。如果匹配,則從for循環執行提前退出(break)。或者,根據您想要實現的內容,只需在第一次匹配時從方法中獲得returnitems.last_updated(注意早期的return語句可能會影響性能)。

+0

你的回答聽起來很合理。我試圖以您建議的方式更改代碼。現在仍然存在的問題是,如何在退貨後設置休息時間?查看新的編輯。 –

1

你需要用來初始化它的開頭:

var age: Int = 0 

如果由於某種原因,你的for循環鴕鳥政策執行,那麼你不容設置你的年齡變量時,你只需要聲明它作爲var age: Int和沒有啓動它。

以及有關:

I even tried to set var age: Int = 0 at the beginning, but then the function return 0

這意味着,你有你的intilizied向age variable0 for循環,其中從未執行,回報將是0

+0

所以我到底需要初始化var age:Int = 0 ? –

+0

而不是'var age:int' do'var age:Int = 0' –

+0

那麼,我總是會'0' –

2

我不是Swift開發者,但我懷疑這些邏輯是正確的。假設你按照其他答案中的建議將age初始化爲0,當你在數組中找到匹配「Steven」的元素後,你應該退出。否則,下一次迭代可能會將年齡再次設置爲零。

請記住,默認情況下,for語句遍歷所有元素。如果你想迭代直到滿足條件,那麼while可能更適合。

我讀過tutorial並使用swift sand box在線測試此代碼。在this link上分享我的代碼。

class AGE { 
    static func getAge() -> Int { 
     var age = 0 
     var found = false 
     var current = 0 
     var allElementsChecked = (dataArray.count == 0) //is false unless array is empty 
     while !found && !allElementsChecked { 
      found = (dataArray[current].name == "Steven") 
      allElementsChecked = (current == dataArray.count-1) 
      current += 1 
     } 
     if found 
     { 
      age = dataArray[current-1].age //minus 1 to undo last increment within loop 
     } 
     return age 
    } 
} 

當從循環中出來時,可能是因爲「Steven」被找到或者所有元素都被檢查並未找到。

2

正如其他答案中提到的問題是,如果數組爲空,變量將永遠不會被設置。

除此之外,如果Steven是數組中的最後一項,那麼您的代碼效率低下,並且僅返回預期結果。否則變量age獲取與0

儘管如此覆蓋在夫特有更方便的方法來篩選的陣列比一個重複循環中的項目,例如first(where:

class AGE { 

    static func getAge() -> Int { 
     return dataArray.first(where: { $0.name == "Steven" })?.age ?? 0 
    } 
} 

,或者它可能是優選的,返回nil如果Steven是不是數組中

class AGE { 

    static func getAge() -> Int? { 
     return dataArray.first(where: { $0.Name == "Steven" })?.age 
    } 
} 

PS:last_updated在你的代碼是不相關的結構Person在所有。

+0

我不理解的東西:如果我在for循環中進行打印輸出,那麼時間會變長。 (見我的新的第三個代碼)。不一定有辦法讓功能中的「年齡」值被拋出去嗎? –

+0

當然,你說得對。我糾正了。如果我使用你建議的代碼,我會得到錯誤:「無法調用非函數類型'Person'的值」 –