【发布时间】:2018-01-16 18:38:36
【问题描述】:
对于 Swift 开发来说相对较新。试图修改其他人编写的几个函数。目标是在用户登录后第一次调用此路径时(该部分尚未设置)离开原始路径,并在后续调用中使用另一个路径。
所以在编写将指向第一次或非首次通过的逻辑之前,我正在测试非首次通过逻辑。
这里是 allOfferCards():
func allOfferCards() -> [OfferCard]{
guard dataSource != nil else {
return []
}
let numberOfCards = self.dataSource!.kolodaNumberOfCards(self)
var offerCards = [OfferCard]()
for i in 0..<numberOfCards {
let offerCard = viewForCard(at: i)
if let offerCard = offerCard {
offerCards.append(offerCard as! OfferCard)
}
}
return offerCards
}
这就是我尝试进行更改的地方。原始逻辑反转 allOfferCards() 的返回。我想使用一个名为“shuffle”的自定义函数来随机化数组。
func displayOfferCards() -> Void {
// What was here originally
//let offerCards = allOfferCards().reversed()
var offerCards = allOfferCards().shuffle()
for (index, offerCard) in offerCards.enumerated() {
let delay = Double(index) * 0.2
offerCard.display(delay: delay)
}
}
这是随机播放功能
extension Array
{
/** Randomizes the order of an array's elements. */
mutating func shuffle()
{
for _ in 0..<10
{
sort { (_,_) in arc4random() < arc4random() }
}
}
}
但是,当我尝试运行此程序时,标题中出现错误 - 无法在不可变值上使用变异成员。但是我不确定为什么 allOfferCards() 会生成一个不可变的值 - var offerCards 是使用 var 关键字定义的,而不是 let 关键字 - 这应该意味着它是可变的正确的?
我在这里做错了什么?
【问题讨论】:
-
这是一个非常非常糟糕的洗牌算法。
sort不会将每个元素都与其他元素进行比较,这样做会非常低效。如果它检查并看到a < b和c < d,那么它可以检查b < c以推断a < b < c < d而无需检查a < c、a < d等等...看看使用适当的Fisher-Yates随机播放:stackoverflow.com/a/24029847/3141234 -
@Alexander - 哦,谢谢,我会这样做的。
-
另外,第一个函数可以简化为两行:gist.github.com/amomchilov/df144a2bee19b627e2163254a42a8a59
-
我最初没有写它——我们知道有很多逻辑可以重写以提高效率(有些已经有了)。我会看看这个,看看它是否符合我们在这里的计划。
-
我知道在这样的代码库上工作的感觉,你不想过多地干扰工作状态。幸运的是,这就是我们拥有 VCS 的原因,以保持良好的安全网,防止无意的破坏性更改。但从长远来看,像这样的小增量变化确实会累积并导致实质性改进。我基本上是免费给你的,所以不妨接受它:p