【问题标题】:Randomly generated array works only on buttons随机生成的数组仅适用于按钮
【发布时间】:2017-08-05 19:14:36
【问题描述】:

我尝试了很多方法来从现有数组中随机生成一个数组。其中一个终于为我解决了:

    extension Array {
    mutating func shuffle() {
// get data from my FireBase and calculate amount of items in it
        var ref: DatabaseReference?
        var databaseHandle: DatabaseHandle?
        var words = [lWord]()
        ref = Database.database().reference()
            guard let uid = Auth.auth().currentUser?.uid else {
                print ("smt wrong with user uid")
                return
            }
           databaseHandle = ref?.child("Users").child(uid).child("LearningNow").observe(.value, with: { (snapshot) in
                var newItems: [lWord] = []
                for item in snapshot.children {
                    let wordItem = lWord(snapshot: item as! DataSnapshot)
                    newItems.append(wordItem)
                }
                words = newItems
            })
        let count = words.count + 1
        for _ in 0..<count  {
            sort { (_,_) in arc4random() < arc4random() }
        }
    }
}

但是,由于某些原因,此代码仅在我将此方法放在按钮操作内的数组上时才有效,例如:

@IBAction func generate(_ sender: UIButton) {
    words.shuffle()
    print (words)
}

如果在viewDidLoad 中放入完全相同的代码,则不会排序。那么如何在不采取任何操作的情况下对数组进行排序呢?

附:如果您不知道答案,您可以推荐任何其他方法来生成随机数组。谢谢!

【问题讨论】:

  • 您没有看到"smt wrong with user uid" 打印输出,是吗?
  • 不,我不知道。 Firebase 工作正常
  • 最可能的问题是viewDidLoad 中执行的更改被稍后执行的代码覆盖。看看将相同的代码放入viewWillAppear 是否可以解决问题。
  • 不,它也不起作用。也许问题是我两次从 FireBase 检索相同的数据?第一次在ViewDidLoad中,第二次在扩展中,不然不知道怎么约束for循环那里,因为数组中的项数可以不一样。
  • 尝试将for _ in 循环放在.observe 的完成处理程序中,就在words = newItems 的正下方

标签: ios arrays swift sorting


【解决方案1】:

感谢您的所有回复!我找到了解决方案,我不得不替换我的方法(代码来自this问题):

extension Array {
/// Returns an array containing this sequence shuffled
var shuffled: Array {
    var elements = self
    return elements.shuffle()
}
/// Shuffles this sequence in place
@discardableResult
mutating func shuffle() -> Array {
    indices.dropLast().forEach {
        guard case let index = Int(arc4random_uniform(UInt32(count - $0))) + $0, index != $0 else { return }
        swap(&self[$0], &self[index])
    }
    return self
}
var chooseOne: Element { return self[Int(arc4random_uniform(UInt32(count)))] }
func choose(_ n: Int) -> Array { return Array(shuffled.prefix(n)) }
}

如您所见,我不会为这种方法从 FireBase 检索数据。所以,也许问题就在那里。

【讨论】:

    猜你喜欢
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 2016-10-10
    • 2013-10-21
    • 2020-10-13
    相关资源
    最近更新 更多