用于Swift中的循环和开关

问题描述 投票:0回答:3

我(相对)是编程新手。我正在研究Apple的“应用程序开发简介”,由于没有某种形式的答案手册,因此我不得不自己解决问题。但是有些事情让我有些困惑:

我正在解决一个问题:

此操场上建有鸡型。鸡具有品种和脾气属性,并且两个属性都是枚举。

[这里有一些鸡:鸡= [{silkie,grumpy} ...]

任务是计算阵列中有多少只“来克亨鸡”和“脾气暴躁”的鸡。我想出了以下代码:

var chickenOfInterestCount = 0

for chicken in chickens {
    switch chicken.temper {
    case .hilarious:
        switch chicken.breed {
        case .leghorn:
            chickenOfInterestCount += 1
        default:
            chickenOfInterestCount += 0
        }
    default:
        chickenOfInterestCount += 0
    }
}


chickenOfInterestCount

它有效,但是我想知道是否有更有效的方法来做到这一点?我可以让交换机检查每只鸡是否有{来克亨鸡,热闹}并直接计算所需鸡的数量,而不是使用嵌套开关吗? (我所有尝试这样做的尝试都被可怕的错误消息所压制,所以我猜没有。)接下来,for循环如何工作?

[当我最初学习循环时,给人的印象是整数用于循环,例如第一个循环是i = 0,执行了内部代码,然后第二个循环是i = 1,依此类推,其中“ i”可以是任何东西,并且想法是相同的。在此,使用“鸡肉”。为什么可以将条件设​​置为chicken.temper?鸡在这里是什么意思? for循环是否尊重其循环通过的数组的类型?那么,这里实际发生的是什么事情,例如“拿起鸡排中的第0只鸡,称其为'鸡肉',然后检查其脾气”?

swift for-loop switch-statement
3个回答
1
投票

在这种情况下,Swift-y要做的事情是分解map()reduce()compactMap()filter()-就您而言,filter()

let chickens: [Chicken] = [ silkie, grumpy, dopey, foghorn ]

let hilariousLeghorns = chickens.filter { 
    $0.breed == .leghorn 
        && $0.temper == .hilarious 
}

let chickenOfInterestCount = hilariousLeghorns.count

(感谢您使您的示例变得有趣!)

在您的伪代码中,您的for循环有点嵌套,这可能很难阅读。 (我的可能并不容易,我很喜欢进行代码审查!)实际上,您在声明一个chicken,它将依次为chickens的每个元素分配值。您可以使用任何Sequence,例如数组,映射或集合。

要获得老式的for循环,可以循环选择一个范围:

for i in 1...5 { 
    print(i)
}

这也做同样的事情:i被依次赋予值1、2、3、4和5,循环5次。


1
投票

欢迎使用编程。这是您的方案的模型。

  struct Chicken{
        let id:Int
        let breed:String
        let temper:String
    }

    enum Breed{
        static let leghorn = "leghorn"
        static let other = "other"
    }

    enum Temper{
        static let hilarious = "hilarious"
        static let other = "other"
    }


    var chickens:[Chicken] = []
    chickens.append(Chicken(id: 1, breed: Breed.leghorn, temper: Temper.hilarious))
    chickens.append(Chicken(id: 2, breed: Breed.other, temper: Temper.hilarious))
    chickens.append(Chicken(id: 3, breed: Breed.leghorn, temper: Temper.other))

您可以使用Swift从一行中获得结果。使用过滤器功能。这类似于for循环,$ 0表示当前元素。它遍历数组并查找满足条件的元素。

print(chickens.filter({$0.breed == Breed.leghorn && $0.temper == Temper.hilarious}).count)

Apple Documentation

Extra info


0
投票

嗯,我首先要提到的是您的方法有效。您怀疑这不是最优雅的方法-但您已经本能地意识到这一点。

Swift中的过滤器功能强大而高效,Dilan的示例将为您提供正确的方向,以开始探索这一点。但是,除了诸如map,reduce和filter之类的功能编程功能之外,您还需要自己对控制流有一个很好的了解。

在这种情况下,如果您只想寻找品种和性情的一种组合,那么基本的if语句可能比使用switch更干净。

var chickenOfInterestCount = 0

for chicken in chickens {
    if chicken.breed == .leghorn && chicken.temper == .hilarious {
        chickenOfInterestCount += 1
    }
}

chickenOfInterestCount

当您必须为每种情况做某事时,Switch会更有用-最终,它比使用多个if / else if语句更为简洁。

var bantamCount = 0
var leghornCount = 0
var unknownBreedCount = 0

var chillCount = 0
var hilariousCount = 0
var unknownTemperCount = 0

for chicken in chickens {

    switch chicken.breed {
    case .bantam:
        bantamCount += 1
    case .leghorn:
        leghornCount += 1
    default:
        unknownBreedCount += 1
    }

    switch chicken.temper {
    case .chill:
        chillCount += 1
    case .hilarious:
        hilariousCount += 1
    default:
        unknownTemperCount += 1
    }

}

也您的问题:

所以这里实际上发生了什么,例如“拿起第0只鸡,称其为'鸡肉',然后检查其脾气”?

正如Ben所指出的,您正在正确地对此进行推理。在循环的范围内,有一个名为chicken的var,它是Chicken的一个实例(大概是-不知道您将其命名为Class还是Struct),并且是chickens数组的成员。

© www.soinside.com 2019 - 2024. All rights reserved.