在Swift中,是否有一种聪明的方法来使用数组上的高阶方法来返回5个第一个对象? obj-c的方法是保存一个索引,而for-loop则通过数组将索引值递增到5,然后返回新的数组。有办法做到这一点与过滤器,映射或减少?
当前回答
斯威夫特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
其他回答
你可以很容易地做到这一点,不需要filter, map, reduce或prefix,只需要通过下标返回数组的一个范围:
var wholeArray = [1, 2, 3, 4, 5, 6]
var n = 5
var firstFiveSlice = wholeArray[0..<n] // 1,2,3,4,5
let firstFiveArray = Array(firstFiveSlice)
简单明了
extension Array {
func first(elementCount: Int) -> Array {
let min = Swift.min(elementCount, count)
return Array(self[0..<min])
}
}
为了获取数组的前5个元素,你所需要做的就是对数组进行切片。在Swift中,你可以这样做:array[0..<5]。
为了使选择数组的前N个元素更具功能性和可泛化性,您可以创建一个扩展方法来执行此操作。例如:
extension Array {
func takeElements(var elementCount: Int) -> Array {
if (elementCount > count) {
elementCount = 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()]
使用Swift 5,根据您的需要,您可以选择以下6个Playground代码之一,以解决您的问题。
# 1。使用下标(_:)
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array[..<5]
//let arraySlice = array[0..<5] // also works
//let arraySlice = array[0...4] // also works
//let arraySlice = array[...4] // also works
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]
# 2。使用前缀(_:)方法
复杂度:O(1)如果集合符合RandomAccessCollection;否则,O(k),其中k是要从集合开始选择的元素的数量。
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(5)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]
Apple声明前缀(_:):
如果最大长度超过集合中的元素数量,则结果包含集合中的所有元素。
# 3。使用prefix(upTo:)方法
复杂性:O (1)
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(upTo: 5)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]
Apple声明前缀(upTo:):
使用前缀(upTo:)方法相当于使用部分半开放范围作为集合的下标。下标表示法优先于前缀(upTo:)。
# 4。使用prefix(through:)方法
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let arraySlice = array.prefix(through: 4)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]
# 5。使用removeSubrange(_:)方法
复杂度:O(n),其中n是集合的长度。
var array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
array.removeSubrange(5...)
print(array) // prints: ["A", "B", "C", "D", "E"]
# 6。使用dropLast(_:)方法
复杂度:O(1)如果集合符合RandomAccessCollection;否则,O(k),其中k是要删除的元素的数量。
let array = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
let distance = array.distance(from: 5, to: array.endIndex)
let arraySlice = array.dropLast(distance)
let newArray = Array(arraySlice)
print(newArray) // prints: ["A", "B", "C", "D", "E"]