быстрое преобразование диапазона <Int> в [Int]


107

как преобразовать диапазон в массив

Я попытался:

let min = 50
let max = 100
let intArray:[Int] = (min...max)

получить ошибку Range<Int> is not convertible to [Int]

Я также пробовал:

let intArray:[Int] = [min...max]

и

let intArray:[Int] = (min...max) as [Int] 

они тоже не работают.

Ответы:


205

Вам нужно создатьArray<Int> используя Range<Int>вместо литых ИНГ его.

let intArray: [Int] = Array(min...max)

1
спасибо, я только что подумал, пока вы отправляли свой ответ
Хайтам

Кажется, что происходит сбой, если диапазон большой: let valuesArray: [Int64] = Array (1 ... 4294967292) - может быть, потому, что он может обрабатывать только Int, а не Int64?
Дэниел Спрингер

2
@DanielSpringer: Проблема не в значении в массиве, а в индексе, превышающем границы, установленные в спецификации языка. Пожалуйста, посчитайте, сколько оперативной памяти вам нужно только для хранения этого огромного массива.
user unknown

@userunknown, значит, не тип значения, а количество значений? Попался, спасибо!
Дэниел Спрингер,

1
@Daniel Springer, это похоже на задачу, в которой вам определенно следует использовать RandomGenerator, см. Некоторые варианты здесь: hackingwithswift.com/articles/102/…
Клаус Буссе,



13

делать:

let intArray = Array(min...max)

Это должно работать, потому Arrayчто инициализатор принимает SequenceTypeи Rangeсоответствует SequenceType.


10

Использовать map

let min = 50
let max = 100
let intArray = (min...max).map{$0}

Добавление того, почему это работает, будет полезно для людей, которые читают такие вопросы. Например, заявив, что он создает CoutableClosedRange, который реализует протокол Sequence, поэтому карта возможна, и она лениво выдает новый int при выполнении операции карты. Некоторые
базовые

Другие ответы интересны, но этот действительно отвечает на вопрос. Большой.
Дэн Розенстарк,

3

Интересно, что вы не можете (по крайней мере, с Swift 3 и Xcode 8) Range<Int>напрямую использовать объект:

let range: Range<Int> = 1...10
let array: [Int] = Array(range)  // Error: "doesn't conform to expected type 'Sequence'"

Поэтому, как упоминалось ранее, вам нужно вручную "развернуть" диапазон, например:

let array: [Int] = Array(range.lowerBound...range.upperBound)

Т.е. можно использовать только буквальный.


Причина в том, что диапазоны не являются коллекциями. Различие между Range и Countable Range заключается в том, что последний может повторяться целочисленным значением. По этой причине Countable Range - это быстрый тип коллекции, а range - нет.
Кори

Верно, и я этого не ожидал, то есть два разных класса диапазона. Вероятно, из-за интерпретации Python range().
devforfu

1

Начиная с Swift 3 / Xcode 8 есть CountableRangeтип, который может пригодиться:

let range: CountableRange<Int> = -10..<10
let array = Array(range)
print(array)
// prints: 
// [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Он может быть использован непосредственно в for- inпетлях:

for i in range {
    print(i)
}

Это (сейчас) правильный способ справиться с задачей. Также работает в Swift 4.
Ash

0

Вы можете реализовать интервалы экземпляров ClosedRange и Range с помощью reduce () в таких функциях.

func sumClosedRange(_ n: ClosedRange<Int>) -> Int {
    return n.reduce(0, +)
}
sumClosedRange(1...10) // 55


func sumRange(_ n: Range<Int>) -> Int {
    return n.reduce(0, +)
}
sumRange(1..<11) // 55
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.