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.

Respostas:


204

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

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

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


14

Eu descobri:

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

Dar crédito a outra pessoa.


13

Faz:

let intArray = Array(min...max)

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


10

Usar map

let min = 50
let max = 100
let intArray = (min...max).map{$0}

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.


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)
}

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.