在Swift中,是否有一种聪明的方法来使用数组上的高阶方法来返回5个第一个对象? obj-c的方法是保存一个索引,而for-loop则通过数组将索引值递增到5,然后返回新的数组。有办法做到这一点与过滤器,映射或减少?


当前回答

Swift 4保存数组类型

extension Array {
    func take(_ elementsCount: Int) -> [Element] {
        let min = Swift.min(elementsCount, count)
        return Array(self[0..<min])
    }
}

其他回答

接这个分机。它修复了原来可怕的命名:

public extension Array {
    func first(_ count: Int) -> ArraySlice<Element> {
        return self.prefix(count)
    }
    
    func last(_ count: Int) -> ArraySlice<Element> {
        return self.suffix(count)
    }
}

用法:

someArr.first(5) 
someArr.last(5) 

Swift 4保存数组类型

extension Array {
    func take(_ elementsCount: Int) -> [Element] {
        let min = Swift.min(elementsCount, count)
        return Array(self[0..<min])
    }
}

斯威夫特4

一个不同的解决方案:

一个简单的内联解决方案,不会崩溃,如果你的数组太短

[0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 3 ? $0.element : nil }

但是用这个很好。

[0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 1000 ? $0.element : nil }

如果你这样做,通常会崩溃:

[0,1,2,3,4,5].prefix(upTo: 1000) // THIS CRASHES

[0,1,2,3,4,5].prefix(1000) // THIS DOESNT

我稍微改变了Markus的答案,将其更新为最新的Swift版本,因为你的方法声明中的var不再被支持:

extension Array {
    func takeElements(elementCount: Int) -> Array {
        if (elementCount > count) {
            return Array(self[0..<count])
        }
        return Array(self[0..<elementCount])
    }
}

对于对象数组,您可以从Sequence创建一个扩展。

extension Sequence {
    func limit(_ max: Int) -> [Element] {
        return self.enumerated()
            .filter { $0.offset < max }
            .map { $0.element }
    }
}

用法:

struct Apple {}

let apples: [Apple] = [Apple(), Apple(), Apple()]
let limitTwoApples = apples.limit(2)

// limitTwoApples: [Apple(), Apple()]