szybka konwersja Range <Int> na [Int]

107

jak przekonwertować Range na Array

Próbowałem:

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

uzyskać błąd Range<Int> is not convertible to [Int]

Próbowałem też:

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

i

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

one też nie działają.

haitham
źródło

Odpowiedzi:

204

Musisz utworzyćArray<Int> używając Range<Int>zamiast obsada ing go.

let intArray: [Int] = Array(min...max)
David Skrundz
źródło
1
dzięki, po prostu to wymyśliłem, kiedy wysłałeś swoją odpowiedź
haitham
Wydaje się, że powoduje awarię, jeśli zakres jest duży: let valuesArray: [Int64] = Array (1 ... 4294967292) - może dlatego, że obsługuje tylko Int, a nie Int64?
Daniel Springer,
2
@DanielSpringer: To nie wartość w tablicy powoduje problem, ale indeks przekracza granice ustalone w specyfikacji języka. Proszę obliczyć, ile pamięci RAM potrzebujesz, tylko do przechowywania tej ogromnej tablicy.
użytkownik nieznany
@userunknown, więc nie typ wartości, ale ilość wartości? Mam cię, dzięki!
Daniel Springer,
1
@Daniel Springer, to brzmi jak zadanie, w którym zdecydowanie powinieneś użyć RandomGenerator, zobacz kilka opcji tutaj: hackingwithswift.com/articles/102/…
Klaus Busse
37

Umieść Range w pliku init.

let intArray = [Int](min...max)
Panie Beardsley
źródło
Idealny! Dzięki @MrBeardsley
Phillip Jacobs
14

Rozgryzłem to:

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

Kredytowanie kogoś innego.

haitham
źródło
13

robić:

let intArray = Array(min...max)

Powinno to zadziałać, ponieważ Arrayinicjator przyjmuje a SequenceTypei Rangejest zgodny z SequenceType.

ad121
źródło
10

Posługiwać się map

let min = 50
let max = 100
let intArray = (min...max).map{$0}
vadian
źródło
Dodanie, dlaczego to działa, byłoby korzystne dla osób czytających tego typu pytania. Na przykład stwierdzenie, że tworzy CoutableClosedRange, który implementuje protokół Sequence, dlatego mapowanie jest możliwe i daje nowy int leniwie podczas wykonywania operacji na mapie. Pewna podstawowa wiedza jest zawsze dobra
denis631
Inne odpowiedzi są interesujące, ale ta faktycznie odpowiada na pytanie. Duże.
Dan Rosenstark
3

Ciekawe, że nie możesz (przynajmniej w Swift 3 i Xcode 8) używać Range<Int>obiektu bezpośrednio:

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

Dlatego, jak wspomniano wcześniej, musisz ręcznie „rozpakować” swój zakres, na przykład:

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

Oznacza to, że możesz używać tylko dosłownego.

devforfu
źródło
Powodem tego jest to, że zakresy nie są kolekcjami. Różnica między zakresem i policzalnym zakresem polega na tym, że ten ostatni może być iterowany przez wartość całkowitą. Z tego powodu Countable Range jest typem kolekcji w swift, ale range nie.
Corey Zambonie
Zgadza się i nie spodziewałem się tego, tj. Dwóch różnych klas zasięgu. Prawdopodobnie z powodu interpretacji Pythona range().
devforfu
1

Od Swift 3 / Xcode 8 istnieje CountableRangetyp, który może być przydatny:

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]

Może być stosowany bezpośrednio w for- inpętlach:

for i in range {
    print(i)
}
killobatt
źródło
To jest (teraz) właściwy sposób na wykonanie zadania. Działa również w Swift 4.
Ash
0

Możesz zaimplementować interwały instancji ClosedRange & Range za pomocą redukuj () w funkcjach takich jak ta.

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
Edison
źródło