швидко перетворити діапазон <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] 

вони також не працюють.

Відповіді:


204

Вам потрібно створитиArray<Int> використовуючи Range<Int>замість литих ІНГ його.

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

1
дякую, я щойно зрозумів це, поки ви надсилали свою відповідь
haitham

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

2
@DanielSpringer: Не значення в масиві викликає проблему, а індекс, що перевищує межі, зафіксовані в специфікації мови. Будь ласка, обчисліть, скільки потрібно оперативної пам’яті, просто для утримання цього величезного масиву.
користувач невідомий

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

1
@Daniel Springer, це звучить як завдання, де вам обов'язково слід скористатися RandomGenerator, дивіться деякі варіанти тут: hackingwithswift.com/articles/102/…
Klaus Busse


14

Я зрозумів це:

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

Надання кредиту комусь іншому.


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, тому карта можлива, і вона дає новий лінь, ліниво виконуючи операцію з картою. Деякі основні знання завжди хороші
denis631

Інші відповіді цікаві, але ця насправді відповідає на питання. Великий вгору.
Дан

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)

Тобто ви можете використовувати лише буквальне.


Причиною цього є те, що діапазони не є колекціями. Відмінність діапазону від діапазону та лічильника полягає в тому, що останній може бути повторений за допомогою цілого значення. З цієї причини лічильник діапазонів - це тип колекції швидко, але діапазон - ні.
Corey Zambonie

Це правильно, і я цього не очікував, тобто два класи різних класів. Можливо, завдяки пітонічній інтерпретації о 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.
Еш

0

Ви можете реалізувати інтервали примірників ClosedRange & Range із зменшенням () у таких функціях.

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.