如何快速返回数组的前5个对象?

时间:2022-05-02 16:32:47

In Swift, is there a clever way of using the higher order methods on Array to return the 5 first objects? The obj-c way of doing it was saving an index, and for-loop through the array incrementing index until it was 5 and returning the new array. Is there a way to do this with filter, map or reduce?

在Swift中,是否有一种巧妙的方法使用数组上的高阶方法来返回第5个对象?object -c的方法是保存一个索引,并通过数组递增索引进行for-loop,直到它是5,然后返回新的数组。是否有一种方法可以使用过滤器、映射或减少?

9 个解决方案

#1


217  

By far the neatest way to get the first N elements of a Swift array is using prefix(maxLength: Int):

到目前为止,获得Swift数组的前N个元素的最整洁的方法是使用前缀(maxLength: Int):

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

This has the benefit of being bounds safe. If the count you pass to prefix is larger than the array count then it just returns the whole array.

这样做的好处是边界安全。如果您传递给前缀的计数大于数组计数,那么它将返回整个数组。

NOTE: as pointed out in the comments, Array.prefix actually returns an ArraySlice, not an Array. In most cases this shouldn't make a difference but if you need to assign the result to an Array type or pass it to a method that's expecting an Array param you will need to force the result into an Array type: let first5 = Array(someArray.prefix(5))

注:如注释中所指出的,数组。前缀实际上返回ArraySlice,而不是数组。在大多数情况下,这不会有什么影响,但是如果您需要将结果分配给数组类型,或者将结果传递给期望使用数组参数的方法,则需要将结果强制为数组类型:let first5 = Array(someArray.prefix(5)))

#2


88  

Update: There is now the possibility to use prefix to get the first n elements of an array. Check @mluisbrown's answer for an explanation how to use prefix.

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

Original Answer: You can do it really easy without filter, map or reduce by just returning a range of your array:

原始答案:你可以很容易地做到没有过滤器,映射或减少仅仅返回你的数组的范围:

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

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

#3


20  

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]

#4


17  

With Swift 4, according to your needs, you may choose one of the 6 following Playground codes in order to solve your problem.

使用Swift 4,根据您的需要,您可以选择以下6个游戏代码中的一个来解决您的问题。


#1. Using subscript(_:) 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. Using prefix(_:) method

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. Using prefix(upTo:) method

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. Using prefix(through:) method

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. Using removeSubrange(_:) method

Complexity: O(n), where n is the length of the collection.

复杂度: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. Using dropLast(_:) method

Complexity: O(n), where n is the number of elements to drop.

复杂度: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"]

#5


13  

For getting the first 5 elements of an array, all you need to do is slice the array in question. In Swift, you do it like this: array[0..<5].

要获取数组的前5个元素,您所需要做的就是对该数组进行切片。在Swift中,您可以这样操作:array[0..<5]。

To make picking the N first elements of an array a bit more functional and generalizable, you could create an extension method for doing it. For instance:

为了使数组的N个第一个元素更有功能和一般化,您可以创建一个扩展方法来完成它。例如:

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

#6


10  

SWIFT 4

斯威夫特4

A different solution:

一个不同的解决方案:

An easy inline solution that wont crash if your array is too short

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

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

But works fine with this.

但是这个方法很有效。

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

Usually this would crash if you did this:

通常情况下,如果你这样做的话,它会崩溃:

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

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

#7


3  

Update for swift 4:

更新迅速4:

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

For swift 3:

为迅速3:

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

#8


2  

I slightly changed Markus' answer to update it for the latest Swift version, as var inside your method declaration is no longer supported:

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

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

#9


0  

Swift 4 with saving array types

具有保存数组类型的Swift 4。

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

#1


217  

By far the neatest way to get the first N elements of a Swift array is using prefix(maxLength: Int):

到目前为止,获得Swift数组的前N个元素的最整洁的方法是使用前缀(maxLength: Int):

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

This has the benefit of being bounds safe. If the count you pass to prefix is larger than the array count then it just returns the whole array.

这样做的好处是边界安全。如果您传递给前缀的计数大于数组计数,那么它将返回整个数组。

NOTE: as pointed out in the comments, Array.prefix actually returns an ArraySlice, not an Array. In most cases this shouldn't make a difference but if you need to assign the result to an Array type or pass it to a method that's expecting an Array param you will need to force the result into an Array type: let first5 = Array(someArray.prefix(5))

注:如注释中所指出的,数组。前缀实际上返回ArraySlice,而不是数组。在大多数情况下,这不会有什么影响,但是如果您需要将结果分配给数组类型,或者将结果传递给期望使用数组参数的方法,则需要将结果强制为数组类型:let first5 = Array(someArray.prefix(5)))

#2


88  

Update: There is now the possibility to use prefix to get the first n elements of an array. Check @mluisbrown's answer for an explanation how to use prefix.

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

Original Answer: You can do it really easy without filter, map or reduce by just returning a range of your array:

原始答案:你可以很容易地做到没有过滤器,映射或减少仅仅返回你的数组的范围:

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

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

#3


20  

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]

#4


17  

With Swift 4, according to your needs, you may choose one of the 6 following Playground codes in order to solve your problem.

使用Swift 4,根据您的需要,您可以选择以下6个游戏代码中的一个来解决您的问题。


#1. Using subscript(_:) 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. Using prefix(_:) method

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. Using prefix(upTo:) method

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. Using prefix(through:) method

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. Using removeSubrange(_:) method

Complexity: O(n), where n is the length of the collection.

复杂度: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. Using dropLast(_:) method

Complexity: O(n), where n is the number of elements to drop.

复杂度: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"]

#5


13  

For getting the first 5 elements of an array, all you need to do is slice the array in question. In Swift, you do it like this: array[0..<5].

要获取数组的前5个元素,您所需要做的就是对该数组进行切片。在Swift中,您可以这样操作:array[0..<5]。

To make picking the N first elements of an array a bit more functional and generalizable, you could create an extension method for doing it. For instance:

为了使数组的N个第一个元素更有功能和一般化,您可以创建一个扩展方法来完成它。例如:

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

#6


10  

SWIFT 4

斯威夫特4

A different solution:

一个不同的解决方案:

An easy inline solution that wont crash if your array is too short

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

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

But works fine with this.

但是这个方法很有效。

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

Usually this would crash if you did this:

通常情况下,如果你这样做的话,它会崩溃:

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

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

#7


3  

Update for swift 4:

更新迅速4:

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

For swift 3:

为迅速3:

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

#8


2  

I slightly changed Markus' answer to update it for the latest Swift version, as var inside your method declaration is no longer supported:

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

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

#9


0  

Swift 4 with saving array types

具有保存数组类型的Swift 4。

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