随机排列swift 3 [英] Shuffle array swift 3

查看:129
本文介绍了随机排列swift 3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将下面的功能转换为swift 3?当前出现Binary operator '..<' cannot be applied to operands of type 'Int' and 'Self.IndexDistance'错误.

How can I convert the function below to to swift 3? Currently getting a Binary operator '..<' cannot be applied to operands of type 'Int' and 'Self.IndexDistance' error.

extension MutableCollection where Index == Int {
  /// Shuffle the elements of `self` in-place.
  mutating func shuffleInPlace() {
    // empty and single-element collections don't shuffle
    if count < 2 { return }

    for i in 0..<count - 1 { //error takes place here
      let j = Int(arc4random_uniform(UInt32(count - i))) + i
      guard i != j else { continue }
      swap(&self[i], &self[j])
    }
  }
}

参考: https://stackoverflow.com/a/24029847/5222077

推荐答案

count返回IndexDistance,该类型描述 两个集合索引之间的距离. IndexDistance是 必须是SignedInteger,但不必是Int,并且可以 与Index不同.因此,无法创建 范围0..<count - 1.

count returns an IndexDistance which is the type describing the distance between two collection indices. IndexDistance is required to be a SignedInteger, but need not be an Int and can be different from Index. Therefore it is not possible to create the range 0..<count - 1.

一种解决方案是使用startIndexendIndex而不是0count:

A solution is to use startIndex and endIndex instead of 0 and count:

extension MutableCollection where Index == Int {
    /// Shuffle the elements of `self` in-place.
    mutating func shuffle() {
        // empty and single-element collections don't shuffle
        if count < 2 { return }

        for i in startIndex ..< endIndex - 1 {
            let j = Int(arc4random_uniform(UInt32(endIndex - i))) + i
            if i != j {
                swap(&self[i], &self[j])
            }
        }
    }
}

另一个优点是,它也可以与数组 slices 一起正常工作 (其中第一个元素的索引不一定为零).

Another advantage is that this also works correctly with array slices (where the index of the first element is not necessarily zero).

请注意,根据新的"Swift API设计指南" shuffle()是变异随机播放方法的适当"名称, 和shuffled()表示返回数组的非变异副本:

Note that according to the new "Swift API Design Guidelines", shuffle() is the "proper" name for a mutating shuffle method, and shuffled() for the non-mutating counterpart which returns an array:

extension Collection {
    /// Return a copy of `self` with its elements shuffled
    func shuffled() -> [Iterator.Element] {
        var list = Array(self)
        list.shuffle()
        return list
    }
}

更新:已向其中添加了一个(甚至更通用的)Swift 3版本 如何在Swift中对数组进行混洗?在此期间.

Update: A (even more general) Swift 3 version has been added to How do I shuffle an array in Swift? in the meantime.

对于 Swift 4(Xcode 9),必须替换对swap()的调用 通过调用集合的swapAt()方法来实现此功能. 同样,不再需要Index类型的限制:

For Swift 4 (Xcode 9) one has to replace the call to the swap() function by a call to the swapAt() method of the collection. Also the restriction on the Index type is no longer needed:

extension MutableCollection {
    /// Shuffle the elements of `self` in-place.
    mutating func shuffle() {
        for i in indices.dropLast() {
            let diff = distance(from: i, to: endIndex)
            let j = index(i, offsetBy: numericCast(arc4random_uniform(numericCast(diff))))
            swapAt(i, j)
        }
    }
}

请参见 SE-0173添加 有关swapAt的更多信息.

See SE-0173 Add MutableCollection.swapAt(_:_:) for more information about swapAt.

Swift 4.2 (Xcode 10,目前处于测试版)开始,随着 SE-0202随机统一shuffle()shuffled()是Swift标准库的一部分.

As of Swift 4.2 (Xcode 10, currently in beta), with the implementation of SE-0202 Random Unification, shuffle() and shuffled() are part of the Swift standard library.

这篇关于随机排列swift 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆