在Swift中重复数组

时间:2016-05-08 03:32:52

标签: arrays swift

在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]

4 个答案:

答案 0 :(得分:13)

您可以创建一个2D数组,然后使用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)或类似方法,则可以避免这种歧义。

答案 1 :(得分:4)

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

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]

答案 2 :(得分:1)

使用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 :(得分:0)

解决方案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]