В Swift есть умный способ использования методов более высокого порядка в Array для возврата 5 первых объектов?
Путем выполнения этого было сохранение индекса и for-loop через индекс инкремента массива до 5 и возврат нового массива. Есть ли способ сделать это с помощью filter
, map
или reduce
?
Как вернуть первые 5 объектов массива в Swift?
Ответ 1
Безусловно, самый лучший способ получить первые N элементов массива Swift - использовать 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
. В большинстве случаев это не должно иметь значения, но если вам нужно присвоить результат типу Array
или передать его методу, ожидающему параметр Array
вам нужно будет принудительно преобразовать результат в тип Array
: let first5 = Array(someArray.prefix(5))
Ответ 2
Update:
Теперь можно использовать prefix
для получения первых n элементов массива. Отметьте @mluisbrown answer для объяснения того, как использовать префикс.
Исходный ответ:
Вы можете сделать это очень легко без filter
, map
или reduce
, просто вернув диапазон вашего массива:
var wholeArray = [1, 2, 3, 4, 5, 6]
var n = 5
var firstFive = wholeArray[0..<n] // 1,2,3,4,5
Ответ 3
С Swift 5, в соответствии с вашими потребностями, вы можете выбрать один из 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(_:)
метод
Сложность: 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 заявляет для prefix(_:)
:
Если максимальная длина превышает количество элементов в коллекции, результат содержит все элементы в коллекции.
# 3. Использование prefix(upTo:)
метод 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 заявляет для prefix(upTo:)
:
Использование метода
prefix(upTo:)
эквивалентно использованию частично полуоткрытого диапазона в качестве индекса коллекции.prefix(upTo:)
индекс предпочтительнееprefix(upTo:)
.
# 4. Использование prefix(through:)
метод 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"]
Ответ 4
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 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
Ответ 6
Для получения первых 5 элементов массива все, что вам нужно сделать, - это отрезать массив, о котором идет речь. В Swift вы делаете это так: array[0..<5]
.
Чтобы сделать N первых элементов массива более функциональным и обобщаемым, вы можете создать метод расширения для этого. Например:
extension Array {
func takeElements(var elementCount: Int) -> Array {
if (elementCount > count) {
elementCount = count
}
return Array(self[0..<elementCount])
}
}
Ответ 7
Я немного изменил ответ Маркуса, чтобы обновить его для последней версии Swift, поскольку var
внутри вашего объявления метода больше не поддерживается:
extension Array {
func takeElements(elementCount: Int) -> Array {
if (elementCount > count) {
return Array(self[0..<count])
}
return Array(self[0..<elementCount])
}
}
Ответ 8
Обновление для Swift 4:
[0,1,2,3,4,5].enumerated().compactMap{ $0 < 10000 ? $1 : nil }
Для быстрой 3:
[0,1,2,3,4,5].enumerated().flatMap{ $0 < 10000 ? $1 : nil }
Ответ 9
Swift 4 с сохранением типов массивов
extension Array {
func take(_ elementsCount: Int) -> [Element] {
let min = Swift.min(elementsCount, count)
return Array(self[0..<min])
}
}
Ответ 10
Простой и Простой
extension Array {
func first(elementCount: Int) -> Array {
let min = Swift.min(elementCount, count)
return Array(self[0..<min])
}
}
Ответ 11
Для массива объектов вы можете создать расширение из 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()]
Ответ 12
Swift 4
Чтобы получить первые N элементов массива Swift, вы можете использовать prefix(_ maxLength: Int)
:
Array(largeArray.prefix(5))