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

bog*_*gen 152 arrays swift

在Swift中,是否有一种聪明的方法可以使用Array上的高阶方法返回5个第一个对象?这样做的obj-c方法是保存索引,并循环遍历数组递增索引,直到它为5并返回新数组.有没有办法做到这一点filter,mapreduce

mlu*_*own 365

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

let someArray = [1, 2, 3, 4, 5, 6, 7]
let first5 = someArray.prefix(5) // 1, 2, 3, 4, 5
Run Code Online (Sandbox Code Playgroud)

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

注意:正如评论中指出的那样,Array.prefix实际上会返回一个ArraySlice,而不是一个Array.在大多数情况下,这不应该有所不同,但如果您需要将结果分配给Array类型或将其传递给期望Array参数的方法,则需要将结果强制转换为Array类型:let first5 = Array(someArray.prefix(5))

  • +1这样一个糟糕的名字选择,恕我直言.数组有`dropFirst`和`dropLast`,所以不妨有'takeFirst`和`takeLast`. (30认同)
  • 另外如果你需要`first5`作为一个数组,只需写`let first5 = Array(someArray.prefix(5))` (8认同)
  • `video = Array(video.prefix(5))` (5认同)
  • @mluisbrown对不起,不能同意你:)在我的项目`video = video.prefix(5)`在Xcode 7.2中导致编译错误`无法分配'ArraySlice <Video>'类型的值来输入'[Video] "` (2认同)
  • @ onmyway133`prefix`可能只是Swift 2.x(我不记得它是否在1.x中),但它确实存在于任何支持Swift 2.x的操作系统,即iOS 7及更高版本.Swift功能可用性由Swift版本决定,而不是iOS版本. (2认同)

Chr*_*örz 95

更新: 现在可以使用prefix获取数组的前n个元素.查看@ mluisbrown的答案,了解如何使用前缀的说明.

原始答案: 如果没有filter,map或者reduce只是返回一系列数组,你可以轻松完成:

var wholeArray = [1, 2, 3, 4, 5, 6]
var n = 5

var firstFive = wholeArray[0..<n] // 1,2,3,4,5
Run Code Online (Sandbox Code Playgroud)

  • 如果你只需要来自Swift数组的第一个`n`项,你可以做`wholeArray.prefix(n)`,它具有边界安全的额外好处.如果`n`大于数组大小`prefix`返回整个数组. (71认同)
  • 如果`wholeArray`没有比`n`更多的元素,它将崩溃 (4认同)

Ima*_*tit 49

使用Swift 4.2,根据您的需要,您可以选择以下6个Playground代码中的一个来解决您的问题.


#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"]
Run Code Online (Sandbox Code Playgroud)

#2.使用prefix(_:)方法

复杂性: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"]
Run Code Online (Sandbox Code Playgroud)

Apple声明prefix(_:):

如果最大长度超过集合中的元素数,则结果将包含集合中的所有元素.


#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"]
Run Code Online (Sandbox Code Playgroud)

Apple声明prefix(upTo:):

使用该prefix(upTo:)方法相当于使用部分半开范围作为集合的下标.下标符号优先于prefix(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"]
Run Code Online (Sandbox Code Playgroud)

#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"]
Run Code Online (Sandbox Code Playgroud)

#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"]
Run Code Online (Sandbox Code Playgroud)


neo*_*eye 26

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]
Run Code Online (Sandbox Code Playgroud)


Dav*_*ees 16

SWIFT 4

不同的解决方案:

一个简单的内联解决方案,如果您的阵列太短,不会崩溃

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

但是这很好用.

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

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

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

[0,1,2,3,4,5].prefix(1000) // THIS DOESNT
Run Code Online (Sandbox Code Playgroud)

  • 对于swift3` [0,1,2,3,5,5] .enumerated().flatMap {$ 0.offset <1000?$ 0.element:nil}` (3认同)

Mar*_*kus 14

要获取数组的前5个元素,您需要做的就是对有问题的数组进行切片.在Swift中,你这样做:array[0..<5].

为了使数组的N个第一个元素更具功能性和可推广性,您可以创建一个扩展方法来实现它.例如:

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


que*_*ful 10

斯威夫特 4

要获取 Swift 数组的前 N ​​个元素,您可以使用prefix(_ maxLength: Int)

Array(largeArray.prefix(5))
Run Code Online (Sandbox Code Playgroud)


Leo*_*tim 9

对于对象数组,您可以从序列创建扩展。

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

用法:

struct Apple {}

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

// limitTwoApples: [Apple(), Apple()]
Run Code Online (Sandbox Code Playgroud)


Ant*_*ine 6

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

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


And*_*rew 5

采取这个扩展。它正在修复原来可怕的命名:

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

用法:

someArr.first(5)
someArr.last(5)
Run Code Online (Sandbox Code Playgroud)