数组搜索功能在Swift中不起作用

时间:2017-06-17 12:38:30

标签: swift function search

我承认感觉有点愚蠢,但经过几个小时的尝试后我不得不问:

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
    }
}

此代码有效,(第二次中断)但仅适用于第一个循环。剩下的问题是,如何在循环达到目标后设置返回和中断。返回或中断将阻止另一步。

5 个答案:

答案 0 :(得分:3)

导致age返回前初始化的可能程序流路径并非详尽无遗。如果dataArray为空,则永远不会输入for ... in循环的正文,并且永远不会初始化age。在您的特定示例中解决此问题的最简单方法是在声明时将age初始化为0

关于“意外”0返回,即使dataArray包含name属性值为"Steven"的元素:for ... in中的每个传递的循环包含name属性值为"Steven"的元素,您将age的值重置为0 < / em>的。这意味着,只有当"Steven"值元素是dataArray的最后一个元素时,非0 age值才会存在。我没有看到任何理由在初始化之后再次将age设置为0,因此您可以通过以下方式解决此问题:在匹配的情况下,从break循环执行提前退出(for)。或者,根据您要实现的目标,只需在首次匹配时从方法中return items.last_updated(只需注意早期return语句可能会影响性能)。

答案 1 :(得分:2)

我不是Swift开发者,但我怀疑这些逻辑是否正确。假设您在其他答案中建议将年龄初始化为0,那么在找到匹配&#34; Steven&#34;进入数组,你应该退出。否则,下一次迭代可以将年龄再次设置为零。

请记住,默认情况下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
    }
}

从循环中出来可能是因为&#34; Steven&#34;被发现或所有元素都被检查但未找到。

答案 2 :(得分:2)

如其他答案中所述,问题是如果数组为空,则永远不会设置变量。

除此之外,如果Steven是数组中的最后一项,则代码效率低下并仅返回预期结果。否则,变量age将被0覆盖。

然而在Swift中,过滤数组中的项比使用重复循环更方便,例如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无关。

答案 3 :(得分:1)

您需要在开始时初始化它:

var age: Int = 0

如果由于某种原因你的for循环没有执行,那么当你只宣称它为var age: Int并且没有将其设置为启用时,你就无法设置你的年龄变量。

关于:

  

我甚至尝试在开头设置var age: Int = 0,但接着是。{   函数返回0

这意味着您已将您的age variable0以及从未执行过的for循环进行了入侵,并且返回将为0

答案 4 :(得分:0)

我测试了Vadian的答案,根据您的要求,这似乎是正确的答案。

不过,这里还有其他建议:

首先,根据您的 Person 结构创建另一个数组实例:

var filteredPerson = [Person]()

如果您要根据名字 在dataArray中搜索年龄:

func getAge(of name: String){
     filteredPerson = dataArray.filter { $0.name == name }
     print (filteredPerson[0].age) }

获取“史蒂文”的 age 值:

getAge(of: "Steven")

您将得到结果:23。

请注意,您还可以通过return来获取 Int 值:

func getAge(of name: String) -> Int {
     filteredPerson = dataArray.filter { $0.name == name }
     return filteredPerson[0].age }

另一方面,如果列表中有很多名称,并且您想获得年龄特定 Person 的值,只需添加 lastName 参数:

func getAge(name: String, lastName: String){
     filteredPerson = dataArray.filter { $0.firstName == name && $0.lastName == lastName }
     print (filteredPerson[0].age) }

然后通过调用获取 age 值:

getAge(name: "Steven", lastName: "Miller")

希望这可以以某种方式帮助某人:)