জাভাস্ক্রিপ্টে আপনি কীভাবে অবজেক্টের অ্যারে ক্লোন করবেন?


420

... যেখানে প্রতিটি বস্তুর একই অ্যারের মধ্যে অন্যান্য অবজেক্টের রেফারেন্স রয়েছে?

আমি যখন প্রথম এই সমস্যাটি নিয়ে এসেছি তখন ঠিক তেমন কিছু ছিল

var clonedNodesArray = nodesArray.clone()

জাভাস্ক্রিপ্টে কীভাবে অবজেক্টগুলি ক্লোন করবেন সে সম্পর্কিত তথ্য উপস্থিত থাকবে এবং অনুসন্ধান করা হবে। আমি স্ট্যাকওভারফ্লোতে একটি প্রশ্ন পেয়েছি (খুব একই @ জনআরসিগের উত্তর) এবং তিনি উল্লেখ করেছেন যে jQuery দিয়ে আপনি করতে পারেন

var clonedNodesArray = jQuery.extend({}, nodesArray);

একটি বস্তুর ক্লোন করা যদিও আমি এটি চেষ্টা করেছিলাম, এটি কেবল অ্যারেতে থাকা সামগ্রীর উল্লেখগুলি অনুলিপি করে। তাই যদি আমি

nodesArray[0].value = "red"
clonedNodesArray[0].value = "green"

উভয় নোডের অ্যারে [0] এবং ক্লোনড নোডস অ্যারে [0] এর মান "সবুজ" হিসাবে দেখাবে। তারপরে চেষ্টা করেছি

var clonedNodesArray = jQuery.extend(true, {}, nodesArray);

যা একটি অবজেক্টের গভীর অনুলিপি করে তবে আমি ফায়ারব্যাগ এবং অপেরা ড্রাগনফ্লাই উভয় থেকে যথাক্রমে " অত্যধিক পুনরাবৃত্তি " এবং " নিয়ন্ত্রণ স্ট্যাক ওভারফ্লো " বার্তা পেয়েছি।

তুমি এটা কি ভাবে করবে? এটি এমন কিছু যা এমনকি করাও উচিত নয়? জাভাস্ক্রিপ্টে এটি করার কোনও পুনরায় ব্যবহারযোগ্য উপায় আছে?

উত্তর:


106

আপনার অগভীর অনুলিপি সহ সমস্যাটি হ'ল সমস্ত বস্তু ক্লোন করা হয়নি। প্রতিটি বস্তুর রেফারেন্স প্রতিটি অ্যারেতে স্বতন্ত্র হলেও, একবার আপনি চূড়ান্তভাবে এটির উপর নজর রাখবেন আপনি আগের মতো একই জিনিসটি নিয়ে কাজ করছেন। আপনি যেভাবে এটি ক্লোন করেছেন তাতে কোনও ভুল নেই ... একই ফলাফল অ্যারে.স্লাইস () ব্যবহার করে ঘটবে।

আপনার গভীর অনুলিপিটির সমস্যা হবার কারণ হ'ল আপনি বিজ্ঞপ্তিযুক্ত বিষয়ের উল্লেখগুলি শেষ করছেন with গভীর যতদূর যেতে পারে তত গভীর হবে এবং আপনার যদি একটি চেনাশোনা পেয়ে থাকে তবে ব্রাউজারের অজ্ঞান হওয়া অবধি এটি অসীমভাবে চলতে থাকবে।

যদি ডেটা স্ট্রাকচারকে নির্দেশিত অ্যাসাইক্লিক গ্রাফ হিসাবে উপস্থাপন করা না যায়, তবে আমি নিশ্চিত নই যে আপনি গভীর ক্লোনিংয়ের জন্য একটি উদ্দেশ্যমূলক পদ্ধতি খুঁজে পেতে সক্ষম হবেন। চক্রীয় গ্রাফগুলি অনেকগুলি কর্নার কেস সরবরাহ করে এবং যেহেতু এটি একটি সাধারণ ক্রিয়াকলাপ নয় আমি সন্দেহ করি যে কেউ একটি সম্পূর্ণ সমাধান লিখেছেন (যদি এটি এমনকি সম্ভব হয় - এটিও নাও হতে পারে! তবে আমার এখনই কঠোর প্রমাণ লেখার চেষ্টা করার সময় নেই।)। আমি এই পৃষ্ঠায় ইস্যুতে কিছু ভাল মন্তব্য পেয়েছি ।

আপনার যদি বিজ্ঞপ্তি সংক্রান্ত রেফারেন্স সহ অবজেক্টগুলির একটি অ্যারের গভীর অনুলিপি প্রয়োজন হয় তবে আমি বিশ্বাস করি যে আপনার বিশেষায়িত ডেটা কাঠামো পরিচালনা করতে আপনাকে নিজের পদ্ধতিটি কোড করতে হবে, যেমন এটি একটি মাল্টি-পাস ক্লোন:

  1. এক রাউন্ডে, সমস্ত বস্তুর একটি ক্লোন তৈরি করুন যা অ্যারেতে অন্য অবজেক্টগুলিকে উল্লেখ করে না। প্রতিটি বস্তুর উত্সের ট্র্যাক রাখুন।
  2. রাউন্ড টু, অবজেক্টগুলিকে একসাথে যুক্ত করুন।

1
@ পেট্রিকেডক্লাইজন উত্তরটির জন্য স্থির লিঙ্ক: web.archive.org/web/20140222022056/http://my.opera.com/…
মাইক সিজেন্ডেল

531

যতক্ষণ না আপনার অবজেক্টগুলিতে জেএসএন-সিরিয়ালাইজযোগ্য সামগ্রী রয়েছে (কোনও ফাংশন, না Number.POSITIVE_INFINITY, ইত্যাদি) অ্যারে বা অবজেক্টগুলি ক্লোন করার জন্য কোনও লুপের প্রয়োজন নেই। এখানে একটি খাঁটি ভ্যানিলা এক-লাইন সমাধান।

var clonedArray = JSON.parse(JSON.stringify(nodesArray))

নীচের মন্তব্যগুলির সংক্ষিপ্তসার হিসাবে, এই পদ্ধতির প্রাথমিক সুবিধাটি হ'ল এটি কেবল অ্যারে নিজেই নয়, অ্যারের সামগ্রীগুলিও ক্লোন করে। প্রাথমিক ডাউনসাইডগুলি কেবল জেএসএন-সিরিয়ালাইজযোগ্য সামগ্রীতে কাজ করার সীমা এবং এটির কার্য সম্পাদন (যা একটি sliceভিত্তিক পদ্ধতির চেয়ে উল্লেখযোগ্যভাবে খারাপ )।


118
এটি JSON ডেটার জন্য কাজ করতে পারে তবে আপনার অ্যারেতে কোনও পদ্ধতি বা অবজেক্টের উদাহরণ রয়েছে যাগুলিতে পদ্ধতি রয়েছে, তাদের বিদায় জানাই।
sp0rkyd0rky

12
সতর্কতা অবলম্বন করুন যদি আপনার কাছে এমন একটি অ্যারে থাকে যার মধ্যে মূল্য অনন্ত থাকে। এই মানটি হারিয়ে যায় (পরে নাল হয়)। ( jsfiddle.net/klickagent/ehm4bd3s )
klickagent.ch

13
এই মাত্র সাধারণত একটি খারাপ পদ্ধতির যদি না আপনার অ্যারের শুধুমাত্র প্রিমিটিভের রয়েছে, এবং / অথবা বস্তু যা নিজেদের শুধুমাত্র স্ট্রিং / নম্বর / বুলিয়ান প্রিমিটিভের ধারণ (এমনকি nullএবং undefinedসমস্যার হতে হবে, যেহেতু তাদেরকে JSON তাদের সমর্থন করে না)। তদতিরিক্ত, এটি তুলনামূলকভাবে কম দক্ষ অপারেশন old_array.slice(0);, যা আরও ভাল এবং দ্রুত উভয়ই কাজ করা উচিত।
এক্সএমএল

2
যদি অ্যারের অবজেক্টে ডেটটাইম থাকে, তবে ডেটটাইমের পরিবর্তে স্ট্রিংটি ফিরে আসবে! নতুন তারিখ! == JSON.parse (JSON.stringify (নতুন তারিখ))
মার্কোসায়ান আর্টুর

2
ওপির প্রশ্নের মূল লাইন, যা উপরের এই উত্তরটি পুরোপুরি উপেক্ষা করে: ... যেখানে প্রতিটি বস্তুর একই অ্যারেতে অন্য বস্তুর উল্লেখ রয়েছে?
এক্সএমএল

288

আমি অবজেক্ট.সেসাইন দিয়ে একটি অ্যারের অবজেক্টের ক্লোনিং সমাধান করেছি

const newArray = myArray.map(a => Object.assign({}, a));

বা স্প্রেড সিনট্যাক্স সহ আরও খাটো

const newArray = myArray.map(a => ({...a}));

15
তবে যদি মাইআরাইতে ডাইনোসরগুলির একগুচ্ছ থাকে, নিউআররে একগুচ্ছ অবজেক্ট থাকে। সে খোঁড়া, তুমি কি রাজি নও?
ম্যাথু জেমস ডেভিস

3
সর্বোত্তম পন্থা, যেহেতু এটি অবজেক্টগুলি ফাংশনকে বাঁচিয়ে রাখে, রাথেন তারপরে তাদেরকে JSON.parse (JSON.stringify (nodesArray)) দিয়ে হারিয়ে ফেলেন
বিজ্ঞানীরা

14
আপনি প্রতিস্থাপন করে এই সমাধান করতে পারে @MatthewJamesDavis {}সঙ্গে new Dinosaur()
আগারগড়া

5
অগভীর অনুলিপি গভীর অনুলিপি নয়
সুলতান আসলাম

1
এটি অবজেক্টগুলির একটি বিন্যাসের জন্য দুর্দান্ত কাজ করে, যদি সেই বস্তুগুলিতে কেবল প্রাথমিক বৈশিষ্ট্য থাকে ... যা আমার প্রয়োজন, ধন্যবাদ
মোজভে

154

আপনার যা দরকার তা হ'ল অগভীর অনুলিপি, সত্যিই সহজ উপায় হ'ল:

new_array = old_array.slice(0);

6
আমার মনে হয় না যে আপনাকে পাস করতে হবে 0, আপনি .slice()কমপক্ষে ক্রোমে যেকোন উপায়ে কল করতে পারেন
এসএলএফ

112
এটি আসলে কাজ করে না, তাই না? আমি বলতে চাইছি, এটি কীভাবে বস্তুর অ্যারে ক্লোন করবেন সেই প্রশ্নের উত্তর নয়। এটি একটি সাধারণ অ্যারের ক্লোন করার সমাধান।
বোজডোজ

35
আসলে এটি কোনও অবজেক্ট অ্যারের জন্য কাজ করবে না। ফিরে আসা অ্যারেটি sliceএকটি নতুন অ্যারে হবে তবে এতে মূল অ্যারে অবজেক্টের রেফারেন্স থাকবে।
সেরজিও এ 21

4
এটি কেবল "জেনেরিকস" ইন্ট, স্ট্রিং ইত্যাদির জন্য কাজ করবে তবে অবজেক্টগুলির অ্যারের জন্য নয়।
স্টিফান মিশেভ

5
বস্তুর অ্যারের জন্য এটি আসলে ক্লোন করে না, নতুন_আররে আপডেট করাও পুরানো_আরে আপডেট করবে।
আনাস

43

এই ক্লোনটি করার সর্বোত্তম এবং সর্বাধিক আধুনিক পদ্ধতি নিম্নরূপ:

...ES6 স্প্রেড অপারেটর ব্যবহার করে ।

এখানে সবচেয়ে সহজ উদাহরণ:

var clonedObjArray = [...oldObjArray];

এইভাবে আমরা পৃথক মানগুলিতে অ্যারে ছড়িয়েছি এবং এটিকে []] অপারেটরের সাথে একটি নতুন অ্যারেতে রেখেছি।

এখানে দীর্ঘতর উদাহরণ যা এটি বিভিন্নভাবে কাজ করে তা দেখায়:

let objArray = [ {a:1} , {b:2} ];

let refArray = objArray; // this will just point to the objArray
let clonedArray = [...objArray]; // will clone the array

console.log( "before:" );
console.log( "obj array" , objArray );
console.log( "ref array" , refArray );
console.log( "cloned array" , clonedArray );

objArray[0] = {c:3};

console.log( "after:" );
console.log( "obj array" , objArray ); // [ {c:3} , {b:2} ]
console.log( "ref array" , refArray ); // [ {c:3} , {b:2} ]
console.log( "cloned array" , clonedArray ); // [ {a:1} , {b:2} ]


2
ভাল আধুনিক উত্তর, এটি পুরানো ব্রাউজারগুলির সাথে কাজ করবে না (যেমন 11)
জেলি

1
@ জিলি আমি অনুমান করতে যাচ্ছি কিংপিনেক্স এই লোকদের বাবেলের বা আরও কী কী আপনার কাছে কীভাবে আরও 6 টি বিশ্বব্যাপী উপকারী কিছুতে এস 6 স্থানান্তরিত করার জন্য এই উত্তরটিকে লক্ষ্য করছে is
রাফিন 21 এ 21

61
এই অ্যারেটি কেবল গভীরভাবে অনুলিপি করে, অ্যারেতে প্রতিটি বস্তু নয়।
তোভো সোয়ান

31
@ ToivoSäwén যা বলেছে তা অনুসরণ করতে, এটি অ্যারেগুলিতে গভীর কপি করবে না। এটি এখনও মূল অবজেক্টগুলিকে উল্লেখ করবে তাই আপনি যদি এগুলিকে পরিবর্তন করেন তবে এটি আসল অ্যারেটিকেও প্রভাবিত করবে।
জোয়েল কিনজেল

3
এটি কেবল আদিমদের জন্য কাজ করে। এটি ব্যবহার করে দেখুন: objArray [0] .এ = 3; এবং আপনি দেখতে পাবেন যে ক্লোনডআরায় অবজেক্টের রেফারেন্স একই থাকবে।
সেরজিও কোরিয়া

25

এটি আমার পক্ষে কাজ করে:

var clonedArray = $.map(originalArray, function (obj) {
                      return $.extend({}, obj);
                  });

এবং আপনার যদি অ্যারেতে অবজেক্টগুলির গভীর অনুলিপি প্রয়োজন:

var clonedArray = $.map(originalArray, function (obj) {
                      return $.extend(true, {}, obj);
                  });

1
দেখে মনে হচ্ছে এটি কাজ করবে। আমি ব্যাপক jQuery ব্যবহার এড়াতে চেষ্টা করছি, তাই আমি এটি আমার পরিস্থিতিতে ব্যবহার করব না, তবে লুপ এবং ... এর জন্য কাজ করবে a
বোজডোজ

19
$.evalJSON($.toJSON(origArray));

2
আপনি এই কোড. google.com/p/jquery-json
wmitchell

32
জিকিউ ছাড়াই (আধুনিক ব্রাউজারগুলিতে সূক্ষ্ম):JSON.parse(JSON.stringify(origArray));
ফরেস্টো

আমি এই মন্তব্য দরকারী বলে মনে করি। আমার বাস্তবায়নে আমাকে এমন বস্তুর অ্যারের একটি অনুলিপি তৈরি করতে হবে যাতে নকআউটজেএস পর্যবেক্ষণযোগ্য বৈশিষ্ট্য প্রয়োগ করা হয়েছিল। অনুলিপিটির জন্য কেবল মানগুলি প্রয়োজন, পর্যবেক্ষণযোগ্য-নেস নয়। আমি JSON.parse (ko.toJSON (originalArray)) বা ko.utils.parseJson (ko.toJSON (originalArray)) ব্যবহার করা মানগুলিকে JUST এর অনুলিপি তৈরি করতে। আমার 2 সেন্ট এবং আমার সমাধানটিতে পৌঁছাতে আমাকে সহায়তা করার জন্য আপনাকে ধন্যবাদ।
ওয়েভড্রপ

6
JSON.parse(JSON.stringify(origArray));অবশ্যই সহজ সমাধান।
ইয়র্কউউ

jQuery প্রায়শই অপ্রয়োজনীয়। youmightnotneedjquery.com
এডি জেঙ্কস

9

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

এটি অবজেক্টগুলির ঠিক একই অ্যারে তৈরি করবে।

let newArray = oldArray.map(a => {
               let newObject = {};
               Object.keys(a).forEach(propertyKey => {
                    newObject[propertyKey] = a[propertyKey];
               });
               return newObject ;
});

8

বেদনাদায়ক পুনরাবৃত্তি না করে এবং প্রশ্নে থাকা অবজেক্টের সমস্ত সূক্ষ্ম বিবরণ না জেনে আমার এটি করার সহজ উপায় থাকতে পারে। JQuery ব্যবহার করে, কেবল jQuery ব্যবহার করে আপনার অবজেক্টটিকে JSON এ রূপান্তর করুন $.toJSON(myObjectArray), তারপরে আপনার JSON স্ট্রিং নিন এবং এটিকে আবার কোনও অবজেক্টে মূল্যায়ন করুন। BAM! কাজ ও সম্পন্ন! সমস্যা সমাধান. :)

var oldObjArray = [{ Something: 'blah', Cool: true }];
var newObjArray = eval($.toJSON(oldObjArray));

21
কিছু আধুনিক ব্রাউজারে JSON পদ্ধতি অন্তর্নির্মিত থাকে যাতে আপনি এটি করতে পারেন: JSON.parse (JSON.stringify (MY_ARRAY)) যা দ্রুত হওয়া উচিত। ভাল পরামর্শ।
নিকোলাস আর

1
এবং যদি তারা json2 ব্যবহার না করে, না eval
কামরানিকাস

এটির মধ্যে দুর্দান্ত অভিনয় রয়েছে, তবে দুর্ভাগ্যক্রমে আমি দেখেছি সেরা উত্তর: /
ডিভিড সিলভা

ব্যবহারকারীর ডেটা দিয়ে কোনও কিছু প্রমাণ করবেন না। সাধারণত কখনই ব্যবহার করবেন না eval()। এটি একটি সুরক্ষা ঝুঁকি।
এডিজেঙ্কস

8

আমি এই প্রশ্নের উত্তর দিচ্ছি কারণ "জাভাস্ক্রিপ্টে বস্তুর একটি অ্যারের ক্লোনিং" করার সমস্যার কোনও সহজ এবং সুস্পষ্ট সমাধান বলে মনে হচ্ছে না:

function deepCopy (arr) {
    var out = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        var item = arr[i];
        var obj = {};
        for (var k in item) {
            obj[k] = item[k];
        }
        out.push(obj);
    }
    return out;
}

// test case

var original = [
    {'a' : 1},
    {'b' : 2}
    ];

var copy = deepCopy(original);

// change value in copy
copy[0]['a'] = 'not 1';

// original[0]['a'] still equals 1

এই সমাধানটি অ্যারের মানগুলিকে পুনরায় করে, তারপরে অবজেক্ট কীগুলি পুনরাবৃত্তি করে, পরেরটিটিকে একটি নতুন অবজেক্টে সংরক্ষণ করে এবং তারপরে সেই নতুন অবজেক্টটিকে একটি নতুন অ্যারেতে ঠেলে দেয়।

Jsfiddle দেখুন । দ্রষ্টব্য: অ্যারের মধ্যে থাকা অবজেক্টগুলির জন্য একটি সাধারণ .slice()বা [].concat()যথেষ্ট নয় ।


উত্তরের জন্য ধন্যবাদ, তবে আপনার উত্তরের কমতিগুলি হাইলাইট করা উচিত ছিল। যখন বস্তুগুলির মধ্যে বস্তু থাকে তখন এটি কাজ করে না .. ঠিক?
হর্ষ

এটি অগভীর অনুলিপি তৈরি করবে। গভীর নয়
সুলতান আসলাম

আপনার কোথাও পুনরাবৃত্তি যুক্ত করতে হবে
ডিজিওকো

6

JQuery প্রসারিত ঠিকঠাক কাজ করছে, কেবল আপনাকে নির্দিষ্ট করতে হবে যে আপনি কোনও বস্তুর পরিবর্তে অ্যারে ক্লোনিং করছেন ( প্রসারিত পদ্ধতির পরামিতি হিসাবে instead of পরিবর্তে [] নোট করুন ):

var clonedNodesArray = jQuery.extend([], nodesArray);

2
হুঁ, আপনি যদি এটিকে কম করেন তবে দয়া করে আপনি কেন এমনটি করছেন সে সম্পর্কে একটি মন্তব্য যুক্ত করতে পারেন? অথবা আপনি কি কোডটি প্রথমে চেষ্টা করে দেখতে পারেন এটি কার্যকর হয় কিনা? ধন্যবাদ;)
স্টেফ

1
প্রথম অ্যারেতে কোনও বস্তু পরিবর্তন করার পরে, দ্বিতীয় অ্যারেতে অবজেক্টটি পরিবর্তিত হয়, তাই এটি ঠিক নেই।
স্পিকলিন

6

এই পদ্ধতিটি খুব সহজ এবং আপনি মূল ক্লিকে সংশোধন না করেই আপনার ক্লোনটি সংশোধন করতে পারেন।

// Original Array
let array = [{name: 'Rafael'}, {name: 'Matheus'}];

// Cloning Array
let clone = array.map(a => {return {...a}})

// Editing the cloned array
clone[1].name = 'Carlos';


console.log('array', array)
// [{name: 'Rafael'}, {name: 'Matheus'}]

console.log('clone', clone)
// [{name: 'Rafael'}, {name: 'Carlos'}]


1
এটি একটি অগভীর অনুলিপি যা দুই স্তর গভীর, [...oldArray]এবং oldArray.slice(0)একটি অগভীর অনুলিপি এক স্তর গভীর করতে। সুতরাং এটি দুর্দান্ত উপকারী তবে সত্যিকারের সম্পূর্ণ গভীর ক্লোন নয়।
বেন হুইলার

সত্য গভীর ক্লোনটি lodash.clonedeepএনপিএম থেকে ব্যবহার করা যেতে পারে
রিভেল্ট করুন

5

ড্যানিয়েল লিউ যেমন উল্লেখ করেছেন, চক্রাকার গ্রাফগুলির কিছু সমস্যা রয়েছে। যদি আমার এই সমস্যাটি হয় তবে আমি clone()সমস্যাযুক্ত বস্তুগুলিতে বিশেষ পদ্ধতি যুক্ত করব বা আমি ইতিমধ্যে কোন বস্তু অনুলিপি করে রেখেছি তা মনে রাখব।

আমি এটি একটি ভেরিয়েবল দিয়ে করব copyCountযা আপনি আপনার কোডটিতে প্রতিবার অনুলিপি করবেন 1 দিয়ে বাড়বে। copyCountবর্তমান অনুলিপি-প্রক্রিয়াটির চেয়ে কম থাকা কোনও বস্তু অনুলিপি করা হয়। যদি তা না হয় তবে অনুলিপিটি, যা ইতিমধ্যে বিদ্যমান রয়েছে তা উল্লেখ করা উচিত। এটি মূল থেকে তার অনুলিপিটিতে লিঙ্ক করা প্রয়োজনীয় করে তোলে।

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


4

অ্যারে.স্লাইস একটি অ্যারের বা অ্যারের অংশটি অনুলিপি করতে ব্যবহার করা যেতে পারে .. http://www.devguru.com/Technologies/Ecmascript/Quickref/Slice.html এটি স্ট্রিং এবং সংখ্যার সাথে কাজ করবে .. - একটি স্ট্রিং পরিবর্তন করে একটি অ্যারে অন্যটিকে প্রভাবিত করবে না - তবে অবজেক্টগুলি এখনও রেফারেন্স দ্বারা অনুলিপি করা হয়েছে যাতে এক অ্যারে রেফারেন্স করা অবজেক্টগুলিতে পরিবর্তনগুলি অন্য অ্যারেতে প্রভাব ফেলবে।

এখানে জাভাস্ক্রিপ্ট পূর্বাবস্থায়িত হওয়ার একটি উদাহরণ রয়েছে যা এটির জন্য দরকারী হতে পারে: http://www.ridgway.co.za/archive/2007/11/07/simple-javascript-undo-manager-for-dtos.aspx


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

... এবং ভাল, এটি আসলে খুব খারাপ ধারণা হতে পারে।
wallyqs

এই পদ্ধতির অন্যান্য সিঙ্ক্রোনাইজেশন জটিলতা থাকতে পারে :) .. আপনি কীভাবে জানেন যে স্ন্যাপশট নেওয়ার সময় অ্যারে পরিবর্তন করা হচ্ছে না ?
মার্কেট

লেখক জাভাস্ক্রিপ্ট ব্যবহার করে একটি সাধারণ পূর্বাবস্থায় পরিচালকের প্রয়োগ করেছিলেন যেখানে একটি নিবন্ধে একটি লিঙ্ক যুক্ত করা হয়েছে ..
মার্কেট

4

আমার পদ্ধতি:

var temp = { arr : originalArray };
var obj = $.extend(true, {}, temp);
return obj.arr;

আমাকে মূল অ্যারের একটি সুন্দর, পরিষ্কার, গভীর ক্লোন দেয় - বস্তুর কোনওটিই মূলটিতে ফিরে আসে না :-)


এটি jquery ব্যবহার করে সেরা সমাধান। স্বল্প ও মধুর.
জন হেন্কেল

1
আমি একটি পারফরম্যান্স পরীক্ষা করেছি এবং এই সমাধানটি JSON.stringify সমাধানের চেয়ে প্রায় 2x দ্রুত বলে মনে হচ্ছে।
meehocz

4

লড্যাশ cloneDeepএই উদ্দেশ্যে কাজ করে:

var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);

4

আপনি যদি গভীর ক্লোন ব্যবহার করতে চান তবে JSON.parse (JSON.stringify (আপনার {} বা [])) ব্যবহার করুন

const myObj ={
    a:1,
    b:2,
    b:3
}

const deepClone=JSON.parse(JSON.stringify(myObj));
deepClone.a =12;
console.log("deepClone-----"+myObj.a);
const withOutDeepClone=myObj;
withOutDeepClone.a =12;
console.log("withOutDeepClone----"+myObj.a);


3

ভুলে যান () জেএসের সর্বাধিক অপব্যবহারযোগ্য বৈশিষ্ট্য এবং কোডটি ধীর করে তোলে) এবং স্লাইস (0) (কেবলমাত্র সাধারণ ডেটা ধরণের জন্য কাজ করে)

এটি আমার পক্ষে সেরা সমাধান:

Object.prototype.clone = function() {
  var myObj = (this instanceof Array) ? [] : {};
  for (i in this) {
    if (i != 'clone') {
        if (this[i] && typeof this[i] == "object") {
          myObj[i] = this[i].clone();
        } else 
            myObj[i] = this[i];
        } 
    }
  return myObj;
};

3

এই সমস্যাটি দেখে আমি বেশ হতাশ ছিলাম। স্পষ্টতই সমস্যা দেখা দেয় যখন আপনি জেনেরিক অ্যারে প্রেরণ করুন ex। সুতরাং, এটি ঠিক করার জন্য, আমি একটি সামান্য চেক যুক্ত করেছি এবং এটি জেনেরিক অ্যারে, jQuery অ্যারে এবং যে কোনও অবজেক্টের সাথে পুরোপুরি কাজ করে।

jQuery.extend({
    deepclone: function(objThing) {
        // return jQuery.extend(true, {}, objThing);
        /// Fix for arrays, without this, arrays passed in are returned as OBJECTS! WTF?!?!
        if ( jQuery.isArray(objThing) ) {
            return jQuery.makeArray( jQuery.deepclone($(objThing)) );
        }
        return jQuery.extend(true, {}, objThing);
    },
});

ব্যবহার করে দাওয়াত করুন:

var arrNewArrayClone = jQuery.deepclone(arrOriginalArray);
// Or more simply/commonly
var arrNewArrayClone = $.deepclone(arrOriginalArray);

deepclone? আমি jquery-1.9.1 ব্যবহার করি এবং এটি এই পদ্ধতিটিকে সমর্থন করে না। এটি কি আরও আধুনিক সংস্করণের পদ্ধতি?
ব্যবহারকারী5260143

@ user2783091 তিনি এই ফাংশনটি যুক্ত করতে JQuery বাড়িয়ে দিচ্ছেন। এটি এমন কিছু নয় যা বাক্স থেকে বেরিয়ে আসে
জর্জিএফজি

3

এটি গভীরভাবে অ্যারে, অবজেক্টস, নাল এবং অন্যান্য স্কেলার মানগুলি অনুলিপি করে এবং অ-নেটিভ ফাংশনগুলিতে কোনও বৈশিষ্ট্যও গভীরভাবে অনুলিপি করে (যা বেশ অস্বাভাবিক তবে সম্ভব)। (দক্ষতার জন্য, আমরা অ্যারেতে অ-সংখ্যাগত বৈশিষ্ট্যগুলি অনুলিপি করার চেষ্টা করি না))

function deepClone (item) {
  if (Array.isArray(item)) {
    var newArr = [];
    for (var i = item.length; i-- > 0;) {
      newArr[i] = deepClone(item[i]);
    }
    return newArr;
  }
  if (typeof item === 'function' && !(/\(\) \{ \[native/).test(item.toString())) {
    var obj;
    eval('obj = '+ item.toString());
    for (var k in item) {
      obj[k] = deepClone(item[k]);
    }
    return obj;
  }
  if (item && typeof item === 'object') {
    var obj = {};
    for (var k in item) {
      obj[k] = deepClone(item[k]);
    }
    return obj;
  }
  return item;
}

3

আমি নতুন ECMAScript 6 অবজেক্ট.সেসাইন পদ্ধতিটি ব্যবহার করছি :

let oldObject = [1,3,5,"test"];
let newObject = Object.assign({}, oldObject);

এই পদ্ধতির প্রথম যুক্তিটি হ'ল অ্যারেটি আপডেট হওয়া দরকার, আমরা একটি খালি বস্তুটি পাস করি কারণ আমরা একটি নতুন অবজেক্ট রাখতে চাই।

আমরা এই বাক্য গঠনটিও ব্যবহার করতে পারি যা একই তবে সংক্ষিপ্ত:

let newObject = [...oldObject];

নোট করুন যে এই পদ্ধতিগুলি অ্যারের মধ্যে কেবল অ্যারে এবং অবজেক্টের জন্য রেফারেন্সগুলি অনুলিপি করবে এবং এগুলির নতুন অনুলিপি তৈরি করবে না। বহুমাত্রিক কাঠামোর জন্য এটি বিরতি প্রত্যাশা করে।
বেন হুইলার

2

বহুমাত্রিক অ্যারেগুলি ক্লোন করতে আমরা একটি সাধারণ পুনরাবৃত্তির অ্যারে পদ্ধতি উদ্ভাবন করতে পারি। নেস্টেড অ্যারেগুলির মধ্যে থাকা অবজেক্টগুলি উত্স অ্যারেতে সম্পর্কিত বিষয়গুলিতে তাদের রেফারেন্স রাখে, অ্যারেগুলি তা করবে না।

Array.prototype.clone = function(){
  return this.map(e => Array.isArray(e) ? e.clone() : e);
};

var arr = [ 1, 2, 3, 4, [ 1, 2, [ 1, 2, 3 ], 4 , 5], 6 ],
    brr = arr.clone();
brr[4][2][1] = "two";
console.log(JSON.stringify(arr));
console.log(JSON.stringify(brr));


2

জাভাস্ক্রিপ্টে অ্যারে এবং অবজেক্ট অনুলিপি মূল মানগুলি পরিবর্তন করে, তাই ডিপ কপি এটির জন্য সমাধান।

একটি গভীর অনুলিপি বলতে আসলে একটি নতুন অ্যারে তৈরি করা এবং মানগুলি অনুলিপি করা হয়, যেহেতু যা ঘটে তা কখনই মূলটির উপর প্রভাব ফেলবে না।

JSON.parseএবং JSON.stringifyডিপ কপি করার সর্বোত্তম এবং সহজ উপায়। JSON.stringify()পদ্ধতি পরিবর্তিত একটি JSON- string.The করার জন্য একটি জাভাস্ক্রিপ্ট মান JSON.parse()পদ্ধতি JSON স্ট্রিংকে, জাভাস্ক্রিপ্ট মান বা বস্তুর স্ট্রিং দ্বারা বর্ণিত নির্মাণের parses।

// ডিপ ক্লোন

let a = [{ x:{z:1} , y: 2}];
let b = JSON.parse(JSON.stringify(a));
b[0].x.z=0

console.log(JSON.stringify(a)); //[{"x":{"z":1},"y":2}]
console.log(JSON.stringify(b)); // [{"x":{"z":0},"y":2}]

আরও তথ্যের জন্য: এখানে পড়ুন


1
এটিই সেরা সমাধান। ধন্যবাদ.
নিকোলে

1

jQuery সহ:

var target= [];
$.each(source, function() {target.push( $.extend({},this));});

1

নিম্নলিখিত কোডটি পুনরাবৃত্তভাবে বস্তু এবং অ্যারের গভীর অনুলিপি সম্পাদন করবে :

function deepCopy(obj) {
if (Object.prototype.toString.call(obj) === '[object Array]') {
    var out = [], i = 0, len = obj.length;
    for ( ; i < len; i++ ) {
        out[i] = arguments.callee(obj[i]);
    }
    return out;
}
if (typeof obj === 'object') {
    var out = {}, i;
    for ( i in obj ) {
        out[i] = arguments.callee(obj[i]);
    }
    return out;
}
return obj;
}

সূত্র


arguments.calleeকঠোর মোডে উপলব্ধ নয় এবং অন্যথায় কর্মক্ষমতা সমস্যা রয়েছে।
ব্রেট জমির

1

জাভাস্ক্রিপ্টে গভীর ক্লোনিংয়ের জন্য কয়েকটি মার্জিত উপায়

https://mootools.net/core/docs/1.6.0/Types/Object

https://scotch.io/bar-talk/copying-objects-in-javascript

1) বস্তু ক্লোনিংয়ের জন্য একটি ভ্যানিলা জাভাস্ক্রিপ্ট পদ্ধতি

2) গভীর ক্লোন বস্তুগুলিতে JSON লাইব্রেরির একটি চৌকস শোষণ

3) jQuery এর ex। সম্প্রসারিত () ফাংশন ব্যবহার করে

4) বস্তু ক্লোন করতে Mootools এর ক্লোন () ফাংশন ব্যবহার


0

আমি মনে করি মূলত Object.createসমস্ত আধুনিক ব্রাউজারগুলিতে সমর্থিত জাভাস্ক্রিপ্ট কাঠামো গভীরভাবে ক্লোনিংয়ের একটি জেনেরিক পদ্ধতি লিখতে পরিচালিত হয়েছে । কোডটি এরকম:

function deepClone (item) {
  if (Array.isArray(item)) {
    var newArr = [];

    for (var i = item.length; i-- !== 0;) {
      newArr[i] = deepClone(item[i]);
    }

    return newArr;
  }
  else if (typeof item === 'function') {
    eval('var temp = '+ item.toString());
    return temp;
  }
  else if (typeof item === 'object')
    return Object.create(item);
  else
    return item;
}

Object.createitemবস্তুর প্রোটোটাইপ হিসাবে বিবেচনা করবে তবে এটি ক্লোনিং থেকে আলাদা different যদি itemসংশোধন করা হয়, পরিবর্তনগুলি তার "ক্লোন" এবং তার বিপরীতে প্রতিফলিত হবে। এই পদ্ধতির কাজ করে না।
ব্রেট জমির

0

পাশাপাশি অবজেক্টস ক্লোনিং করার জন্য আমি কেবল ECMAScript 6 টি সুপারিশ করতে যাচ্ছিলাম reduce():

const newArray=myArray.reduce((array, element)=>array.push(Object.assign({}, element)), []);

তবে খোলামেলাভাবে আমি @ জিনোডসরাস এর উত্তর আরও ভাল পছন্দ করি। আমি এই সংস্করণটিকে অন্য বিকল্প হিসাবে এখানে রাখছি তবে ব্যক্তিগতভাবে আমি map()@ জিনোডসরাস দ্বারা প্রস্তাবিত হিসাবে ব্যবহার করব ।


0

আপনার যদি এখানে অ্যান্ডস্কোর বা ব্যাবেল রয়েছে তা নির্ভর করে কোনও অ্যারে গভীরভাবে ক্লোনিং করার বিভিন্ন উপায়ের একটি বেঞ্চমার্ক।

https://jsperf.com/object-rest-spread-vs-clone/2

দেখে মনে হচ্ছে বাবেল সবচেয়ে দ্রুত।

var x = babel({}, obj)

0
       var game_popularity = [
            { game: "fruit ninja", popularity: 78 },
            { game: "road runner", popularity: 20 },
            { game: "maze runner", popularity: 40 },
            { game: "ludo", popularity: 75 },
            { game: "temple runner", popularity: 86 }
        ];
        console.log("sorted original array before clonning");
        game_popularity.sort((a, b) => a.popularity < b.popularity);
        console.log(game_popularity);


        console.log("clone using object assign");
        const cl2 = game_popularity.map(a => Object.assign({}, a));
        cl2[1].game = "clash of titan";
        cl2.push({ game: "logan", popularity: 57 });
        console.log(cl2);


        //adding new array element doesnt reflect in original array
        console.log("clone using concat");
        var ph = []
        var cl = ph.concat(game_popularity);

        //copied by reference ?
        cl[0].game = "rise of civilization";

        game_popularity[0].game = 'ping me';
        cl.push({ game: "angry bird", popularity: 67 });
        console.log(cl);

        console.log("clone using ellipses");
        var cl3 = [...game_popularity];
        cl3.push({ game: "blue whale", popularity: 67 });
        cl3[2].game = "harry potter";
        console.log(cl3);

        console.log("clone using json.parse");
        var cl4 = JSON.parse(JSON.stringify(game_popularity));
        cl4.push({ game: "home alone", popularity: 87 });
        cl4[3].game ="lockhead martin";
        console.log(cl4);

        console.log("clone using Object.create");
        var cl5 = Array.from(Object.create(game_popularity));
        cl5.push({ game: "fish ville", popularity: 87 });
        cl5[3].game ="veto power";
        console.log(cl5);


        //array function
        console.log("sorted original array after clonning");
        game_popularity.sort((a, b) => a.popularity < b.popularity);
        console.log(game_popularity);


        console.log("Object.assign deep clone object array");
        console.log("json.parse deep clone object array");
        console.log("concat does not deep clone object array");
        console.log("ellipses does not deep clone object array");
        console.log("Object.create does not deep clone object array");


        Output:


        sorted original array before clonning
        [ { game: 'temple runner', popularity: 86 },
        { game: 'fruit ninja', popularity: 78 },
        { game: 'ludo', popularity: 75 },
        { game: 'maze runner', popularity: 40 },
        { game: 'road runner', popularity: 20 } ]
        clone using object assign
        [ { game: 'temple runner', popularity: 86 },
        { game: 'clash of titan', popularity: 78 },
        { game: 'ludo', popularity: 75 },
        { game: 'maze runner', popularity: 40 },
        { game: 'road runner', popularity: 20 },
        { game: 'logan', popularity: 57 } ]
        clone using concat
        [ { game: 'ping me', popularity: 86 },
        { game: 'fruit ninja', popularity: 78 },
        { game: 'ludo', popularity: 75 },
        { game: 'maze runner', popularity: 40 },
        { game: 'road runner', popularity: 20 },
        { game: 'angry bird', popularity: 67 } ]
        clone using ellipses
        [ { game: 'ping me', popularity: 86 },
        { game: 'fruit ninja', popularity: 78 },
        { game: 'harry potter', popularity: 75 },
        { game: 'maze runner', popularity: 40 },
        { game: 'road runner', popularity: 20 },
        { game: 'blue whale', popularity: 67 } ]
        clone using json.parse
        [ { game: 'ping me', popularity: 86 },
        { game: 'fruit ninja', popularity: 78 },
        { game: 'harry potter', popularity: 75 },
        { game: 'lockhead martin', popularity: 40 },
        { game: 'road runner', popularity: 20 },
        { game: 'home alone', popularity: 87 } ]
        clone using Object.create
        [ { game: 'ping me', popularity: 86 },
        { game: 'fruit ninja', popularity: 78 },
        { game: 'harry potter', popularity: 75 },
        { game: 'veto power', popularity: 40 },
        { game: 'road runner', popularity: 20 },
        { game: 'fish ville', popularity: 87 } ]
        sorted original array after clonning
        [ { game: 'ping me', popularity: 86 },
        { game: 'fruit ninja', popularity: 78 },
        { game: 'harry potter', popularity: 75 },
        { game: 'veto power', popularity: 40 },
        { game: 'road runner', popularity: 20 } ]

        Object.assign deep clone object array
        json.parse deep clone object array
        concat does not deep clone object array
        ellipses does not deep clone object array
        Object.create does not deep clone object array
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.