Swift convert Range <Int> para [Int]

107

como converter Range em Array

Eu tentei:

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

obter erro Range<Int> is not convertible to [Int]

Eu também tentei:

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

e

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

eles também não funcionam.

Haitham
fonte

Respostas:

204

Você precisa criar um Array<Int>usando o, em Range<Int>vez de fundi -lo.

let intArray: [Int] = Array(min...max)
David Skrundz
fonte
1
obrigado, acabei de descobrir enquanto você enviava sua resposta
haitham
Isso parece travar se o intervalo for grande: let valuesArray: [Int64] = Array (1 ... 4294967292) - talvez porque ele só pode lidar com Int e não Int64?
Daniel Springer
2
@DanielSpringer: Não é o valor no Array que causa o problema, mas o índice excedendo os limites fixados na especificação da linguagem. Calcule quanta RAM você precisa, apenas para manter este enorme Array.
usuário desconhecido
@userunknown não é o tipo de valor, mas a quantidade de valores? Te peguei, obrigado!
Daniel Springer de
1
@Daniel Springer, parece uma tarefa em que você definitivamente deveria usar um RandomGenerator, veja algumas opções aqui: hackingwithswift.com/articles/102/…
Klaus Busse
37

Coloque o intervalo no init.

let intArray = [Int](min...max)
Sr. Beardsley
fonte
Perfeito! Obrigado @MrBeardsley
Phillip Jacobs
14

Eu descobri:

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

Dar crédito a outra pessoa.

Haitham
fonte
13

Faz:

let intArray = Array(min...max)

Isso deve funcionar porque Arraytem um inicializador usando a SequenceTypee Rangeestá em conformidade com SequenceType.

ad121
fonte
10

Usar map

let min = 50
let max = 100
let intArray = (min...max).map{$0}
vadiana
fonte
adicionar por que funciona seria benéfico para as pessoas que estão lendo esse tipo de perguntas. Por exemplo, afirmando que ele cria um CoutableClosedRange que implementa o protocolo Sequence, portanto, o map é possível e produz um novo int preguiçosamente ao executar a operação do mapa. Algum conhecimento prévio é sempre bom
denis631
As outras respostas são interessantes, mas esta realmente responde à pergunta. Engrandecer.
Dan Rosenstark
3

Interessante que você não pode (pelo menos, com Swift 3 e Xcode 8) usar o Range<Int>objeto diretamente:

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

Portanto, como foi mencionado anteriormente, você precisa "desembrulhar" manualmente seu intervalo como:

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

Ou seja, você pode usar apenas literal.

Devforfu
fonte
A razão para isso é porque os intervalos não são coleções. A distinção entre Intervalo e Intervalo contável é que o último pode ser iterado por um valor inteiro. Por essa razão, Countable Range é um tipo de coleção em swift, mas range não é.
Corey Zambonie
Isso mesmo, e eu não esperava por isso, ou seja, duas classes de alcance diferentes. Provavelmente devido à interpretação Pythônica de range().
devforfu
1

Desde Swift 3 / Xcode 8, há um CountableRangetipo que pode ser útil:

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]

Pode ser usado diretamente em for- inloops:

for i in range {
    print(i)
}
killobatt
fonte
Esta é (agora) a maneira correta de lidar com a tarefa. Também funciona em Swift 4.
Ash
0

Você pode implementar intervalos de instância ClosedRange e Range com reduce () em funções como esta.

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
fonte