swift convert Range <Int> en [Int]

107

comment convertir Range en Array

J'ai essayé:

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

obtenir une erreur Range<Int> is not convertible to [Int]

J'ai aussi essayé:

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

et

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

ils ne fonctionnent pas non plus.

haitham
la source

Réponses:

204

Vous devez créer un en Array<Int>utilisant Range<Int>plutôt que de le lancer .

let intArray: [Int] = Array(min...max)
David Skrundz
la source
1
merci, je viens de le
comprendre
Cela semble planter si la plage est grande: laissez valuesArray: [Int64] = Array (1 ... 4294967292) - peut-être parce qu'il ne peut gérer que Int et non Int64?
Daniel Springer
2
@DanielSpringer: Ce n'est pas la valeur du tableau, qui cause le problème, mais l'index dépassant les limites fixées dans la spécification du langage. Veuillez calculer la quantité de RAM dont vous avez besoin, juste pour contenir cet énorme tableau.
utilisateur inconnu
@userunknown donc pas le type de valeur, mais la quantité de valeurs? Gotcha, merci!
Daniel Springer le
1
@Daniel Springer, cela ressemble à une tâche où vous devriez certainement utiliser un générateur aléatoire, voir pour quelques options ici: hackingwithswift.com/articles/102/…
Klaus Busse
37

Mettez la plage dans le fichier init.

let intArray = [Int](min...max)
Monsieur Beardsley
la source
Parfait! Merci @MrBeardsley
Phillip Jacobs
14

Je l'ai compris:

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

Donner du crédit à quelqu'un d'autre.

haitham
la source
13

faire:

let intArray = Array(min...max)

Cela devrait fonctionner car Arrayun initialiseur prend a SequenceTypeet se Rangeconforme à SequenceType.

ad121
la source
10

Utilisation map

let min = 50
let max = 100
let intArray = (min...max).map{$0}
vadian
la source
ajouter pourquoi cela fonctionne serait bénéfique pour les personnes qui lisent ce genre de questions. Par exemple, en déclarant qu'il crée un CoutableClosedRange qui implémente le protocole Sequence, la carte est donc possible et elle donne un nouvel int paresseusement lors de l'exécution d'une opération de carte. Certaines connaissances de base sont toujours bonnes
denis631
Les autres réponses sont intéressantes mais celle-ci répond en fait à la question. Dédicace.
Dan Rosenstark
3

Intéressant que vous ne puissiez pas (du moins, avec Swift 3 et Xcode 8) utiliser l' Range<Int>objet directement:

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

Par conséquent, comme cela a été mentionné précédemment, vous devez "déballer" manuellement votre plage comme:

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

C'est-à-dire que vous ne pouvez utiliser que littéral.

devforfu
la source
La raison en est que les plages ne sont pas des collections. La distinction entre Range et Countable Range est que cette dernière peut être répétée par une valeur Integer. Pour cette raison, Countable Range est un type de collection en swift, mais pas range.
Corey Zambonie
C'est vrai, et je ne m'y attendais pas, c'est-à-dire deux classes de gamme différentes. Probablement en raison de l'interprétation pythonique de range().
devforfu
1

Depuis Swift 3 / Xcode 8, il existe un CountableRangetype, qui peut être pratique:

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]

Il peut être utilisé directement dans for- inboucles:

for i in range {
    print(i)
}
Killobatt
la source
C'est (maintenant) la bonne façon de gérer la tâche. Fonctionne également dans Swift 4.
Ash
0

Vous pouvez implémenter des intervalles d'instance ClosedRange & Range avec reduction () dans des fonctions comme celle-ci.

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
la source