แปลงช่วง <Int> เป็น [Int] อย่างรวดเร็ว


108

วิธีการแปลง Range เป็น Array

ฉันเหนื่อย:

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] 

พวกเขาไม่ทำงานเช่นกัน

คำตอบ:


206

คุณจำเป็นต้องสร้างArray<Int>ใช้Range<Int>มากกว่าโยนไอเอ็นจีมัน

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

1
ขอบคุณฉันเพิ่งคิดได้ในขณะที่คุณส่งคำตอบ
haitham

สิ่งนี้ดูเหมือนจะผิดพลาดหากช่วงมีขนาดใหญ่: let valuesArray: [Int64] = Array (1 ... 4294967292) - อาจเป็นเพราะสามารถจัดการได้เฉพาะ Int ไม่ใช่ Int64?
Daniel Springer

2
@DanielSpringer: ไม่ใช่ค่าใน Array ซึ่งทำให้เกิดปัญหา แต่ดัชนีเกินขอบเขตที่กำหนดไว้ในข้อกำหนดภาษา โปรดคำนวณจำนวน RAM ที่คุณต้องการสำหรับการถือ Array ขนาดใหญ่นี้
ไม่ทราบผู้ใช้

@userunknown ไม่ใช่ประเภทของค่า แต่เป็นจำนวนค่า? Gotcha ขอบคุณ!
Daniel Springer

1
@Daniel Springer ฟังดูเหมือนเป็นงานที่คุณควรใช้ RandomGenerator อย่างแน่นอนดูตัวเลือกบางอย่างได้ที่นี่: hackingwithswift.com/articles/102/…
Klaus Busse



13

ทำ:

let intArray = Array(min...max)

สิ่งนี้ควรใช้งานArrayได้เนื่องจากมี initializer ที่รับSequenceTypeและเป็นRangeไปSequenceTypeตาม


10

ใช้ map

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

เพิ่มเติมว่าเหตุใดจึงได้ผลดีสำหรับผู้ที่กำลังอ่านคำถามประเภทนี้ ตัวอย่างเช่นระบุว่าสร้าง CoutableClosedRange ซึ่งใช้โปรโตคอล Sequence ดังนั้นจึงเป็นไปได้ที่แผนที่และให้ int ใหม่อย่างเฉื่อยชาเมื่อดำเนินการกับแผนที่ ความรู้พื้นฐานบางอย่างเป็นสิ่งที่ดีเสมอ
denis631

คำตอบอื่น ๆ น่าสนใจ แต่คำตอบนี้ตอบคำถามได้จริง ขนาดใหญ่ขึ้น.
Dan Rosenstark

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)

กล่าวคือคุณสามารถใช้ตัวอักษรเท่านั้น


สาเหตุนี้เป็นเพราะช่วงไม่ใช่คอลเล็กชัน ความแตกต่างระหว่างช่วงและช่วงที่นับได้คือค่าหลังสามารถวนซ้ำได้ด้วยค่าจำนวนเต็ม ด้วยเหตุนี้ Countable Range จึงเป็นประเภทคอลเลกชันที่รวดเร็ว แต่ไม่ใช่ช่วง
Corey Zambonie

ถูกต้องและฉันไม่ได้คาดหวังสิ่งนี้นั่นคือคลาสสองช่วงที่แตกต่างกัน range()อาจเนื่องมาจากการตีความของ Pythonic
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
Ash

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.