быстрое преобразование диапазона <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/…
Клаус Буссе,
37

Поместите Range в init.

let intArray = [Int](min...max)
Мистер Бердсли
источник
Отлично! Спасибо @MrBeardsley
Филлип Джейкобс
14

Я понял:

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

Отдавать должное кому-то другому.

Хайтам
источник
13

делать:

let intArray = Array(min...max)

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

ad121
источник
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)

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

devforfu
источник
Причина в том, что диапазоны не являются коллекциями. Различие между 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
Эдисон
источник