如何在Swift中将数组拆分成两半?

时间:2015-08-18 13:41:50

标签: arrays swift

如何分割一副纸牌?我有一个阵列和一个随机的卡片经销商,但不知道如何拆分牌组。

感谢大家的帮助!我现在有一个工作卡应用程序,遇到了其他问题但很快就解决了。

5 个答案:

答案 0 :(得分:16)

您可以进行扩展,以便它可以返回两个数组的数组,使用Ints,Strings等:

extension Array {
    func split() -> [[Element]] {
        let ct = self.count
        let half = ct / 2
        let leftSplit = self[0 ..< half]
        let rightSplit = self[half ..< ct]
        return [Array(leftSplit), Array(rightSplit)]
    }
}

let deck = ["J", "Q", "K", "A"]
let nums = [0, 1, 2, 3, 4]

deck.split() // [["J", "Q"], ["K", "A"]]
nums.split() // [[0, 1], [2, 3, 4]]

但返回一个命名元组甚至更好,因为它强制执行这样一个事实,即你期望正好两个数组:

extension Array {
    func split() -> (left: [Element], right: [Element]) {
        let ct = self.count
        let half = ct / 2
        let leftSplit = self[0 ..< half]
        let rightSplit = self[half ..< ct]
        return (left: Array(leftSplit), right: Array(rightSplit))
    }
}

let deck = ["J", "Q", "K", "A"]

let splitDeck = deck.split()
print(splitDeck.left) // ["J", "Q"]
print(splitDeck.right) // ["K", "A"]

注意:获得第一个正确答案的是Andrei和Qbyte,我只是添加信息。

答案 1 :(得分:9)

您可以使用下标范围

let deck: [String] = ["J", "Q", "K", "A"]

// use ArraySlice only for transient computation
let leftSplit: ArraySlice<String> = deck[0 ..< deck.count / 2] // "J", "Q"
let rightSplit: ArraySlice<String> = deck[deck.count / 2 ..< deck.count] // "K", "A"

// make arrays from ArraySlice
let leftDeck: [String] = Array(leftSplit) // "J", "Q"
let rightDeck: [String] = Array(rightSplit) // "K", "A"

编辑:以上代码适用于Swift 2,也许适用于Swift 3是一种更方便的方式。

答案 2 :(得分:8)

快速

更通用的解决方案,将数组分成多个块link

extension Array {
    func chunked(into size: Int) -> [[Element]] {
        return stride(from: 0, to: count, by: size).map {
            Array(self[$0 ..< Swift.min($0 + size, count)])
        }
    }
}
let numbers = Array(1...100)
let result = numbers.chunked(into: 5)

答案 3 :(得分:3)

您可以在SequenceType上创建扩展程序,并创建名为divide的函数。

此函数将遍历序列的元素,同时将与谓词匹配的元素放入一个数组(slice),将那些不匹配的元素放入另一个数组(remainder)。

该函数返回一个包含sliceremainder

的元组
extension SequenceType {

    /**
     Returns a tuple with 2 arrays.
     The first array (the slice) contains the elements of self that match the predicate.
     The second array (the remainder) contains the elements of self that do not match the predicate.
     */
    func divide(@noescape predicate: (Self.Generator.Element) -> Bool) -> (slice: [Self.Generator.Element], remainder: [Self.Generator.Element]) {
        var slice:     [Self.Generator.Element] = []
        var remainder: [Self.Generator.Element] = []
        forEach {
            switch predicate($0) {
            case true  : slice.append($0)
            case false : remainder.append($0)
            }
        }
        return (slice, remainder)
    }

}

这是一个例子

let tuple = [1, 2, 3, 4, 5].divide({ $0 >= 3 })
tuple.slice     // [3, 4, 5]
tuple.remainder // [1, 2]

答案 4 :(得分:0)

还有先前提供的想法的另一种实现。首先,直到Swift当前文档为止,最好使用过去简单时态来选择名称,以产生一些结果,而现在时态则用于变异它们。 其次,对于我来说,最好选择一半加上 count%2 以获得更统一的结果。

在这里:

// in class trigger
void set_callback(std::function<void()> f) {
    _f = f;
}

// in class wrapper
wrapper() {
    _t.set_callback([this](){ some_function(); });
}

结果:

extension Array {
    func splitted() -> ([Element], [Element]) {
        let half = count / 2 + count % 2
        let head = self[0..<half]
        let tail = self[half..<count]

        return (Array(head), Array(tail))
    }
}