我(相对)是编程新手。我正在研究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-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次。
欢迎使用编程。这是您的方案的模型。
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)
嗯,我首先要提到的是您的方法有效。您怀疑这不是最优雅的方法-但您已经本能地意识到这一点。
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数组的成员。