আমি কীভাবে একটি অ্যারের সঠিক সদৃশ নকল করব?


101

আমি কীভাবে একটি অ্যারের হুবহু নকল করব?

সুইফটে একটি অ্যারের সদৃশ করার বিষয়ে তথ্য পেতে আমার বেশ কষ্ট হচ্ছে।

আমি ব্যবহার করার চেষ্টা করেছি .copy()

var originalArray = [1, 2, 3, 4]
var duplicateArray = originalArray.copy()

5
কেন আপনি সরাসরি var duplicateArray = originalArray
এইরূপে

4
আমার ক্ষেত্রে এটি কাজ করে না। এটি অন্য একটি অবজেক্ট তৈরি করে যা একই অ্যারের কেবল একটি রেফারেন্স এবং আপনি একই অ্যারের উল্লেখ করে 2 ভেরিয়েবল সমাপ্ত করেন।
ব্যবহারকারী 1060500

উত্তর:


179

অ্যারেগুলিতে সুইফটে পূর্ণ মান শব্দার্থক শব্দ রয়েছে, তাই অভিনব কোনও কিছুর প্রয়োজন নেই।

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

নোট করুন যে এখানে অসুবিধাগুলি রয়েছে যে সুইফ্টের মান শব্দার্থকগুলি আপনাকে from থেকে রক্ষা করতে কাজ করছে, উদাহরণস্বরূপ, যেহেতু 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 এটি অনুলিপি করা হচ্ছে বলে মনে হচ্ছে না, আপনি কেন জানেন?
ফিল নিদারস্টেচাইডার

@ পিএনগেমিং পাওয়ার: এক্স এর ঠিকানা রয়েছে। y এর মধ্যে এই ঠিকানাগুলির অনুলিপি রয়েছে। আপনি যদি x [0] টি পরিবর্তন করেন তবে y [0] পরিবর্তন হবে না। (x [0] = x [1] চেষ্টা করুন, y [0] পরিবর্তন হবে না)। সুতরাং, y হ'ল x এর একটি গভীর অনুলিপি the তবে আপনি কেবলমাত্র পয়েন্টারগুলি অনুলিপি করেছেন, যা তারা দেখায়।
রাগেরিয়াস

@ রেগানারিয়াস তাই মূলত আমাদের "কপি" এর অর্থ কী তা নির্দেশক বা মানটি অনুলিপি করতে হবে। সুতরাং এটি পয়েন্টারগুলির অ্যারে অনুলিপি করার জন্য সমাধান, তবে আপনি কীভাবে মানগুলির অ্যারে নকল করবেন? লক্ষ্যটি হবে x[0] == x[1]তবে x[0] === y[0]ব্যর্থ হওয়া উচিত
ফিল নিডের্সচাইডার

এটি গ্রহণযোগ্য উত্তর হওয়া উচিত, কারণ অ্যারের মান শব্দার্থবিদ্যা অ্যারের "অনুলিপি" তৈরি করে।
স্কট অহটেন

এটি আমার পক্ষে কাজ করে না। আমি যদি সেই পদ্ধতিটি অনুসরণ করি তবে আমি দুটি রেফারেন্স পেয়েছি যা একই ধরণের অবজেক্টের দিকে ইশারা করে। যদি আমি তালিকা থেকে কোনও আইটেম সরিয়ে ফেলি তবে এটি উভয় অবজেক্টের রেফারেন্সে প্রতিফলিত হয় যেহেতু তালিকাটি অনুলিপি করা হয়নি, বরং বস্তুটি কেবল রেফারেন্স করা হয়েছিল।
ব্যবহারকারী 1060500

29

নাট সঠিক। আপনি যদি আদিম অ্যারেগুলির সাথে কাজ করছেন তবে আপনাকে যা করতে হবে তা হ'ল মূলআরেতে সদৃশ অ্যারিকে অর্পণ করা।

সম্পূর্ণতার স্বার্থে, আপনি যদি এনএসআরাই অবজেক্টে কাজ করছিলেন তবে এনএসআরির সম্পূর্ণ অনুলিপিটি করতে নিম্নলিখিতগুলি করতে হবে:

var originalArray = [1, 2, 3, 4] as NSArray

var duplicateArray = NSArray(array:originalArray, copyItems: true)

এটা অসাধারণ! ধন্যবাদ!
প্যাট্রিক

25

নেটের উত্তরের তৃতীয় বিকল্প রয়েছে:

let z = x.map { $0 }  // different array with same objects

* সম্পাদিত * সম্পাদনা এখানে শুরু হয়

উপরেরটি মূলত নীচের মত একই এবং প্রকৃতপক্ষে নীচের সাম্যতা অপারেটরটি ব্যবহার করা আরও ভাল সম্পাদন করবে কারণ অ্যারেটি পরিবর্তন না করা হলে অনুলিপি করা হবে না (এটি নকশা অনুসারে)।

let z = x

এখানে আরও পড়ুন: https://developer.apple.com/swift/blog/?id=10

* সম্পাদিত * সম্পাদনা এখানেই শেষ হয়

এই অ্যারেতে যুক্ত করা বা অপসারণ মূল অ্যারেটিকে প্রভাবিত করবে না। যাইহোক, অ্যারের ধারণ করে থাকা কোনও বস্তুর কোনও বৈশিষ্ট্য পরিবর্তন করে আসল অ্যারেতে দেখা যাবে। কারণ অ্যারেতে থাকা বস্তুগুলি অনুলিপিগুলি নয় (ধরে নেওয়া অ্যারে ধরে রাখা বস্তুগুলি, আদিম সংখ্যা নয়)।


এটা কার্যকর হয়, আমি এটি পরীক্ষা করেছি। দুটি অ্যারে রয়েছে, যদি আপনি 1 এ পরিবর্তন করেন তবে দ্বিতীয়টি কার্যকর হবে
ফিলিটি নাইট

4
না হয় না, যদি না অ্যারে বস্তুর পরিবর্তে আদিম ধরণের ধারণ করে। তারপরে উত্তরে বর্ণিত হিসাবে এটি প্রভাবিত করে। একটি সাধারণ পরীক্ষার কেস:var array1: [String] = ["john", "alan", "kristen"]; print(array1); var array2 = array1.map { $0 }; print(array2); array2[0] = "james"; print(array1); print(array2);
ওয়ালহি

4
কাস্টম ক্লাসটি ব্যবহার করে আরও ভাল উদাহরণের জন্য আমি তৈরি করা এই গিস্টটি
oialhi

যদি আপনার শ্রেণি সমর্থন করে NSCopyingতবে একটি অ্যারের সদৃশ করুন:let z = x.map { $0.copy as! ClassX }
জন প্যাং

যদি সুইফ্টের বাফারপয়েন্টার ব্যবহার করা হয় তবে এটির সরাসরি অনুলিপি হিসাবে আপনার ব্যবহার করা ভার্সন এটি। মূল বা অনুলিপি করা অ্যারেতে কোনও মান পরিবর্তন করার আগে, সুইফট মূলটির মানগুলিকে অনুলিপি করে অনুলিপি করবে এবং তারপরে অবিরত থাকবে। আপনি যদি এর পরিবর্তে পয়েন্টার ব্যবহার করেন, পরিবর্তনগুলি হয় যখন বা কখন সুইফট হয় না, সুতরাং আপনি সম্ভবত উভয় অ্যারে পরিবর্তন করতে পারেন।
জাস্টিন গ্যাঞ্জার

16

সাধারণ বস্তুর জন্য যা করা যায় তা হ'ল অনুলিপি সমর্থনকারী একটি প্রোটোকল বাস্তবায়ন করা এবং অবজেক্ট শ্রেণি এই প্রোটোকলটিকে এভাবে প্রয়োগ করে:

protocol Copying {
    init(original: Self)
}

extension Copying {
    func copy() -> Self {
        return Self.init(original: self)
    }
}

এবং তারপরে ক্লোনিংয়ের জন্য অ্যারে এক্সটেনশন:

extension Array where Element: Copying {
    func clone() -> Array {
        var copiedArray = Array<Element>()
        for element in self {
            copiedArray.append(element.copy())
        }
        return copiedArray
    }
}

কোড এবং একটি নমুনা দেখতে এই টুকরোটি পরীক্ষা করে দেখুন


এই অনেক সময় সাশ্রয়, ধন্যবাদ।
অভিজিৎ

সাবক্লাসের জন্য প্রোটোকল গ্যারান্টি দিতে পারে না যে প্রয়োজনীয় উদ্যোগটি সাবক্লাসের ধরণের সাথে প্রয়োগ করা হয়েছে। আপনি একটি অনুলিপি প্রোটোকল ঘোষণা করছেন যা আপনার জন্য অনুলিপি প্রয়োগ করে, তবে আপনি এখনও ক্লোন () বাস্তবায়ন করছেন, এটির কোনও মানে হয় না।
বাইনারি

4
@iGodric অনুলিপিটি সংগ্রহে থাকা উপাদানগুলির জন্য এবং ক্লোনটি পুরো সংগ্রহের জন্য থাকে, যখন অনুলিপিগুলির উপাদানগুলির জন্য প্রয়োগ করা হয়। ধারণা তৈরী কর? এছাড়াও, সংকলকটি নিশ্চিত করে যে সাবক্লাসগুলি তাদের পিতামাতার প্রয়োজনীয় প্রোটোকলটি অনুসরণ করে।
জনবেকার্স

@ জোহনবাকার্স ওহ হ্যাঁ, এখন আমি এটি দেখতে পাচ্ছি। ব্যাখ্যার জন্য ধন্যবাদ।
বাইনারি

খুব পরিষ্কার বাস্তবায়ন এবং আর object's
ডি

0

আপনি যদি কিছু শ্রেণীর অবজেক্টের অ্যারের আইটেমগুলি অনুলিপি করতে চান তবে। তারপরে আপনি এনএসকোপিং প্রোটোকলটি ব্যবহার না করে নীচের কোডটি অনুসরণ করতে পারেন তবে আপনার একটি init পদ্ধতি থাকা দরকার যা আপনার অবজেক্টের জন্য প্রয়োজনীয় সমস্ত পরামিতি গ্রহণ করা উচিত। খেলার মাঠে পরীক্ষার জন্য উদাহরণের জন্য এখানে কোড।

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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.