如何在Swift中返回数组的前5个对象?

在Swift中,有没有一种聪明的方法来使用Array上的高阶方法来返回5个第一个对象? 这样做的obj-c方法是保存一个索引,并通过数组增量索引for循环,直到它是5,并返回新的数组。 有没有办法做到这一点与filtermapreduce

更新:现在有可能使用prefix来获取数组的前n个元素。 检查@ mluisbrown的答案 ,以解释如何使用前缀。

原来的答案:你可以做到这一点很简单,没有filtermapreduce只是返回一个数组的范围:

 var wholeArray = [1, 2, 3, 4, 5, 6] var n = 5 var firstFive = wholeArray[0..<n] // 1,2,3,4,5 

到目前为止,获取Swift数组的前N个元素的最简单方法是使用prefix(maxLength: Int)

 let someArray = [1, 2, 3, 4, 5, 6, 7] let first5 = someArray.prefix(5) // 1, 2, 3, 4, 5 

这有利于安全。 如果您传递给prefix的计数大于数组数,那么它只是返回整个数组。

注意:正如在注释中指出的, Array.prefix实际上返回一个ArraySlice ,而不是一个Array 。 在大多数情况下,这应该不会有什么区别,但是如果您需要将结果赋值给Arraytypes或将其传递给需要Array参数的方法,则需要将结果强制为Arraytypes: let first5 = Array(someArray.prefix(5))

 let a: [Int] = [0, 0, 1, 1, 2, 2, 3, 3, 4] let b: [Int] = Array(a.prefix(5)) // result is [0, 0, 1, 1, 2] 

为了得到数组的前5个元素,你需要做的就是切片数组。 在Swift中,你这样做: array[0..<5]

为了使一个数组的N个第一个元素更具function性和泛化性,你可以创build一个扩展方法来实现它。 例如:

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

SWIFT 3

不同的解决scheme:

一个简单的行内解决scheme,如果您的数组太短,不会崩溃

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

但是,这个很好。

 [0,1,2,3,4,5].enumerated().flatMap{ $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 

随着Swift 4,根据您的需要,您可以select以下6个游乐场代码之一,以解决您的问题。


#1。 使用subscript(_:)下标

 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。 使用prefix(_:)方法

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

#3。 使用prefix(upTo:)方法

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

#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( n ),其中n是要删除的元素的数量。

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

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

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

对于迅捷3:

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