【问题标题】:Repeating array in SwiftSwift 中的重复数组
【发布时间】:2016-05-08 03:32:52
【问题描述】:

在 Python 中,我可以像这样创建一个重复列表:

>>> [1,2,3]*3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

在 Swift 中是否有一种简洁的方法可以做到这一点?

我能做的最好的就是:

  1> var r = [Int]()
r: [Int] = 0 values
  2> for i in 1...3 { 
  3.     r += [1,2,3]
  4. }
  5> print(r)
[1, 2, 3, 1, 2, 3, 1, 2, 3]

【问题讨论】:

    标签: arrays swift


    【解决方案1】:

    您可以创建一个二维数组,然后使用flatMap 将其变成一维数组:

    let array = [Int](repeating: [1,2,3], count: 3).flatMap{$0}
    

    这是一个扩展,它添加了一个 init 方法和一个重复方法,该方法采用一个数组,这使得它更简洁:

    extension Array {
      init(repeating: [Element], count: Int) {
        self.init([[Element]](repeating: repeating, count: count).flatMap{$0})
      }
    
      func repeated(count: Int) -> [Element] {
        return [Element](repeating: self, count: count)
      }
    }
    
    let array = [1,2,3].repeated(count: 3) // => [1, 2, 3, 1, 2, 3, 1, 2, 3]
    

    请注意,使用新的初始化程序,如果您在没有提供预期类型的​​情况下使用它,您可能会得到一个模棱两可的方法调用:

    let array = Array(repeating: [1,2,3], count: 3) // Error: Ambiguous use of ‛init(repeating:count:)‛
    

    改用:

    let array = [Int](repeating: [1,2,3], count: 3) // => [1, 2, 3, 1, 2, 3, 1, 2, 3]
    

    let array:[Int] = Array(repeating: [1,2,3], count: 3) // => [1, 2, 3, 1, 2, 3, 1, 2, 3]
    

    如果您将方法签名更改为 init(repeatingContentsOf: [Element], count: Int) 或类似名称,则可以避免这种歧义。

    【讨论】:

    • 您需要将count参数类型更改为Int才能将其用作索引或从Uint强制转换为Int self.init([Array](count: Int(count), repeatedValue: repeatedValues).flatMap{$0})
    • 啊,是的,事实证明,当我测试它时,我使用的代码与我在此处发布的代码略有不同。我对其进行了更改以更好地匹配原始init 方法。
    【解决方案2】:

    使用 Swift 5,您可以创建一个 Array 扩展方法,以便将给定数组的元素重复到一个新数组中。下面的 Playground 示例代码显示了此方法的可能实现:

    extension Array {
    
        func repeated(count: Int) -> Array<Element> {
            assert(count > 0, "count must be greater than 0")
    
            var result = self
            for _ in 0 ..< count - 1 {
                result += self
            }
    
            return result
        }
    
    }
    
    let array = [20, 11, 87]
    let newArray = array.repeated(count: 3)
    print(newArray) // prints: [20, 11, 87, 20, 11, 87, 20, 11, 87]
    

    如果需要,您还可以创建一个中缀运算符来执行此操作:

    infix operator **
    
    extension Array {
    
        func repeated(count: Int) -> Array<Element> {
            assert(count > 0, "count must be greater than 0")
    
            var result = self
            for _ in 0 ..< count - 1 {
                result += self
            }
    
            return result
        }
    
        static func **(lhs: Array<Element>, rhs: Int) -> Array<Element> {
            return lhs.repeated(count: rhs)
        }
    
    }
    
    let array = [20, 11, 87]
    let newArray = array ** 3
    print(newArray) // prints: [20, 11, 87, 20, 11, 87, 20, 11, 87]
    

    【讨论】:

      【解决方案3】:

      您可以使用模运算来计算基本集合的索引并为此进行函数式编程:

      let base = [1, 2, 3]
      let n = 3 //number of repetitions
      let r = (0..<(n*base.count)).map{base[$0%base.count]}
      

      您可以为 * 运算符创建自定义重载,它接受左侧的数组和右侧的整数。

      func * <T>(left: [T], right: Int) -> [T] {
          return (0..<(right*left.count)).map{left[$0%left.count]}
      }
      

      然后你可以像在 python 中一样使用你的函数:

      [1, 2, 3] * 3
      // will evaluate to [1, 2, 3, 1, 2, 3, 1, 2, 3]
      

      【讨论】:

      • 非常酷!但是,我不想在 Swift 中实现 Python 语法。可能不利于代码的可读性。
      【解决方案4】:

      解决方案 1:

      func multiplerArray(array: [Int], time: Int) -> [Int] {
          var result = [Int]()
          for _ in 0..<time {
              result += array
          }
          return result
      }
      

      调用这个

      print(multiplerArray([1,2,3], time: 3)) // [1, 2, 3, 1, 2, 3, 1, 2, 3]
      

      解决方案 2:

      let arrays = Array(count:3, repeatedValue: [1,2,3])
      // [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
      var result = [Int]()
      for array in arrays {
          result += array
      }
      print(result) //[1, 2, 3, 1, 2, 3, 1, 2, 3]
      

      【讨论】:

        猜你喜欢
        • 2019-05-24
        • 1970-01-01
        • 2016-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-22
        相关资源
        最近更新 更多