ฉันจะสร้างอาร์เรย์ที่ซ้ำกันได้อย่างไร
ฉันมีปัญหาในการค้นหาข้อมูลเกี่ยวกับการทำซ้ำอาร์เรย์ใน Swift
ฉันลองใช้ .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
ฉันจะสร้างอาร์เรย์ที่ซ้ำกันได้อย่างไร
ฉันมีปัญหาในการค้นหาข้อมูลเกี่ยวกับการทำซ้ำอาร์เรย์ใน Swift
ฉันลองใช้ .copy()
var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()
คำตอบ:
อาร์เรย์มีความหมายเต็มรูปแบบใน Swift ดังนั้นจึงไม่จำเป็นต้องมีอะไรแปลกใหม่
var duplicateArray = originalArray
คือทั้งหมดที่คุณต้องการ
หากเนื้อหาของอาร์เรย์ของคุณเป็นประเภทการอ้างอิงใช่สิ่งนี้จะคัดลอกตัวชี้ไปยังวัตถุของคุณเท่านั้น ในการคัดลอกเนื้อหาแบบละเอียดคุณจะต้องใช้map
และคัดลอกอินสแตนซ์แต่ละรายการแทน สำหรับคลาสพื้นฐานที่เป็นไปตามNSCopying
โปรโตคอลคุณสามารถใช้copy()
วิธีการ:
let x = [NSMutableArray(), NSMutableArray(), NSMutableArray()]
let y = x
let z = x.map { $0.copy() }
x[0] === y[0] // true
x[0] === z[0] // false
โปรดทราบว่ามีข้อผิดพลาดที่นี่ที่ความหมายของค่าของ Swift กำลังทำงานเพื่อปกป้องคุณจากตัวอย่างเช่นเนื่องจากNSArray
แสดงถึงอาร์เรย์ที่ไม่เปลี่ยนรูปcopy
วิธีของมันจะส่งกลับการอ้างอิงถึงตัวมันเองดังนั้นการทดสอบข้างต้นจะให้ผลลัพธ์ที่ไม่คาดคิด
var x = [UIView(), UIView(), UIView()] var y = x for i in x { NSLog("%p", i) } println("---") for i in y { NSLog("%p", i) }
และฉันได้ผลลัพธ์นี้: 0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770 ---0x7fa82b0009e0 0x7fa82b012660 0x7fa82b012770
ดูเหมือนจะไม่ถูกคัดลอกคุณรู้ไหมว่าทำไม?
x[0] == x[1]
แต่x[0] === y[0]
ควรล้มเหลว
เนทถูกต้อง หากคุณกำลังทำงานกับอาร์เรย์ดั้งเดิมสิ่งที่คุณต้องทำคือกำหนด duplicateArray ให้กับ originalArray
เพื่อความสมบูรณ์หากคุณใช้งานออบเจ็กต์ NSArray คุณจะต้องทำสิ่งต่อไปนี้เพื่อทำสำเนา NSArray แบบเต็ม:
var originalArray = [1, 2, 3, 4] as NSArray
var duplicateArray = NSArray(array:originalArray, copyItems: true)
มีตัวเลือกที่สามสำหรับคำตอบของ Nate:
let z = x.map { $0 } // different array with same objects
* แก้ไข *แก้ไขเริ่มต้นที่นี่
ด้านบนจะเหมือนกับด้านล่างและการใช้ตัวดำเนินการความเท่าเทียมกันด้านล่างจะทำงานได้ดีกว่าเนื่องจากอาร์เรย์จะไม่ถูกคัดลอกเว้นแต่จะมีการเปลี่ยนแปลง (นี่คือการออกแบบ)
let z = x
อ่านเพิ่มเติมที่นี่: https://developer.apple.com/swift/blog/?id=10
* แก้ไข *แก้ไขสิ้นสุดที่นี่
การเพิ่มหรือลบอาร์เรย์นี้จะไม่ส่งผลต่ออาร์เรย์เดิม อย่างไรก็ตามการเปลี่ยนแปลงคุณสมบัติใด ๆ ของวัตถุที่อาร์เรย์ถือจะเห็นได้ในอาร์เรย์ดั้งเดิม เนื่องจากอ็อบเจ็กต์ในอาร์เรย์ไม่ได้คัดลอก (สมมติว่าอ็อบเจ็กต์ยึดอาร์เรย์ไม่ใช่ตัวเลขดั้งเดิม)
var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
NSCopying
ให้ทำซ้ำอาร์เรย์:let z = x.map { $0.copy as! ClassX }
สำหรับวัตถุปกติสิ่งที่สามารถทำได้คือการใช้โปรโตคอลที่รองรับการคัดลอกและทำให้คลาสอ็อบเจ็กต์ใช้โปรโตคอลนี้ดังนี้:
protocol Copying {
init(original: Self)
}
extension Copying {
func copy() -> Self {
return Self.init(original: self)
}
}
จากนั้นส่วนขยาย Array สำหรับการโคลน:
extension Array where Element: Copying {
func clone() -> Array {
var copiedArray = Array<Element>()
for element in self {
copiedArray.append(element.copy())
}
return copiedArray
}
}
และนั่นก็ค่อนข้างดีในการดูโค้ดและตัวอย่างตรวจสอบส่วนสำคัญนี้
object's
ฟังก์ชัน init
หากคุณต้องการคัดลอกรายการของอาร์เรย์ของวัตถุคลาสบางอย่าง จากนั้นคุณสามารถทำตามโค้ดด้านล่างโดยไม่ต้องใช้โปรโตคอล NSCopying แต่คุณต้องมีวิธีการเริ่มต้นซึ่งควรใช้พารามิเตอร์ทั้งหมดที่จำเป็นสำหรับวัตถุของคุณ นี่คือโค้ดสำหรับตัวอย่างการทดสอบในสนามเด็กเล่น
class ABC {
var a = 0
func myCopy() -> ABC {
return ABC(value: self.a)
}
init(value: Int) {
self.a = value
}
}
var arrayA: [ABC] = [ABC(value: 1)]
var arrayB: [ABC] = arrayA.map { $0.myCopy() }
arrayB.first?.a = 2
print(arrayA.first?.a)//Prints 1
print(arrayB.first?.a)//Prints 2
var duplicateArray = originalArray