জাভাস্ক্রিপ্টে একটি অ্যারের নকল করার দ্রুততম উপায় - 'লুপের জন্য' স্লাইস বনাম


634

জাভাস্ক্রিপ্টে একটি অ্যারের সদৃশ করতে: নীচের কোনটি ব্যবহার করা দ্রুত?

স্লাইস পদ্ধতি

var dup_array = original_array.slice();

For লুপ

for(var i = 0, len = original_array.length; i < len; ++i)
   dup_array[i] = original_array[i];

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

আমি শুধু গতি সম্পর্কে জিজ্ঞাসা করছি।


3
jsben.ch/#/wQ9RU <= অ্যারে ক্লোন করার সর্বাধিক প্রচলিত উপায়গুলির একটি মানদণ্ড
EscapeNetscape

উত্তর:


776

কমপক্ষে 5 টি (!) উপায় অ্যারে ক্লোন করার উপায় রয়েছে:

  • লুপ
  • ফালি
  • Array.from ()
  • CONCAT
  • স্প্রেড অপারেটর (দ্রুততম)

নিম্নলিখিত তথ্য সরবরাহ করে একটি হিউজ বেঞ্চমার্কস থ্রেড রয়েছে :

  • জন্য চোখ পিট পিট ব্রাউজার slice(), দ্রুততম পদ্ধতি concat()একটু ধীর, এবং while loop2.4x মন্থর।

  • অন্যান্য ব্রাউজারগুলির while loopজন্য দ্রুততম পদ্ধতি, যেহেতু এই ব্রাউজারগুলির অভ্যন্তরীণ অনুকূলতা থাকে না sliceএবং concat

এটি জুলাই ২০১ in সালে সত্য।

নীচে এমন সাধারণ স্ক্রিপ্টগুলি রয়েছে যা আপনি আপনার ব্রাউজারের কনসোলে কপি-পেস্ট করতে পারেন এবং ছবিটি দেখতে বেশ কয়েকবার চালাতে পারেন। তারা আউটপুট মিলিসেকেন্ড, কম ভাল।

লুপ করার সময়

n = 1000*1000;
start = + new Date();
a = Array(n); 
b = Array(n); 
i = a.length;
while(i--) b[i] = a[i];
console.log(new Date() - start);

ফালি

n = 1000*1000;
start = + new Date();
a = Array(n); 
b = a.slice();
console.log(new Date() - start);

দয়া করে নোট করুন যে এই পদ্ধতিগুলি অ্যারে অবজেক্টটি নিজেই ক্লোন করবে, অ্যারে বিষয়বস্তু তবে রেফারেন্স দ্বারা অনুলিপি করা হয়েছে এবং গভীর ক্লোন নয়।

origAr == clonedArr //returns false
origAr[0] == clonedArr[0] //returns true

48
@ cept0 কোনও আবেগ নেই, কেবল বেঞ্চমার্ক jsperf.com/new-array-vs-splice-vs-slice/31
ড্যান

2
@ ডান তাহলে কি? আপনার পরীক্ষার কেসের ফলাফল: ফায়ারফক্স 30 রাতের মধ্যে ক্রোমের চেয়ে এখনও 230% দ্রুত faster এর জন্য ভি 8 এর উত্স কোডটি পরীক্ষা করে দেখুন spliceএবং আপনি অবাক হয়ে যাবেন (যখন ...)
mate64

4
দুঃখের সাথে সংক্ষিপ্ত অ্যারেগুলির উত্তরটি সম্পূর্ণ ভিন্ন । উদাহরণস্বরূপ শ্রোতাদের প্রত্যেককে কল করার আগে একটি অ্যারের ক্লোনিং করা। এই অ্যারেগুলি প্রায়শই ছোট হয়, সাধারণত 1 টি উপাদান।
gman

6
আপনি এই পদ্ধতিটি মিস করেছেন:A.map(function(e){return e;});
wcochran

13
আপনি ঝলক ব্রাউজার সম্পর্কে লিখছেন । নন নাচা শুধু একটি লেআউট ইঞ্জিন, প্রধানত এইচটিএমএল রেন্ডারিং প্রভাবিত, এবং এইভাবে গুরুত্বহীন? আমি ভেবেছিলাম আমরা বরং ভি 8, স্পাইডারমনকি এবং বন্ধুদের এখানে কথা বলব। শুধু একটি জিনিস যা আমাকে বিভ্রান্ত করেছে। আমি ভুল হলে আমাকে আলোকিত করুন।
নিওনিত

241

টেকনিক্যালি slice হয় দ্রুততম উপায়। তবে আপনি 0সূচনা সূচকটি যুক্ত করলে এটি আরও দ্রুত হয় ।

myArray.slice(0);

তুলনায় দ্রুত

myArray.slice();

http://jsperf.com/cloning-arrays/3


আর এর myArray.slice(0,myArray.length-1);চেয়ে দ্রুত myArray.slice(0);?
jave.web

1
@ jave.web আপনাকে; অ্যারের শেষ উপাদানটি সবেমাত্র ফেলেছে। সম্পূর্ণ অনুলিপিটি অ্যারে.স্লাইস (0) বা অ্যারে.স্লাইস (0, অ্যারে.লেন্থ)
মারেক মার্কজাক

137

এস 6 উপায় সম্পর্কে কি?

arr2 = [...arr1];

23
যদি বাবেলের সাথে রূপান্তরিত হয়:[].concat(_slice.call(arguments))
চ্যান করুন

1
কোথা argumentsথেকে আসছে তা নিশ্চিত নয় ... আমি মনে করি আপনার বাবেল আউটপুট কয়েকটি ভিন্ন বৈশিষ্ট্যকে বিভ্রান্ত করছে। এটি হওয়ার সম্ভাবনা বেশি arr2 = [].concat(arr1)
স্টার্লিং আর্চার

3
@ স্টার্লিংআরচার এর arr2 = [].conact(arr1)থেকে আলাদা arr2 = [...arr1][...arr1]সিনট্যাক্সটি গর্তকে রূপান্তর করবে undefined। উদাহরণস্বরূপ arr1 = Array(1); arr2 = [...arr1]; arr3 = [].concat(arr1); 0 in arr2 !== 0 in arr3,।
tsh

1
আমি উপরের ড্যানের উত্তরের বিপরীতে আমার ব্রাউজারে (Chrome 59.0.3071.115) এটি পরীক্ষা করেছি। এটি .slice () এর চেয়ে 10 গুণ বেশি ধীর ছিল। n = 1000*1000; start = + new Date(); a = Array(n); b = [...a]; console.log(new Date() - start); // 168
হ্যারি স্টিভেনস

1
এখনও ভালো ক্লোন কিছু এগুলি করবেন না: [{a: 'a', b: {c: 'c'}}]। যদি c"সদৃশ" অ্যারে এর মান পরিবর্তন করা হয় তবে এটি মূল অ্যারেতে পরিবর্তিত হবে, কারণ এটি কেবল একটি রেফারেন্সিয়াল অনুলিপি, কোনও ক্লোন নয়।
নিউরোট্রান্সমিটার

44

গভীর ক্লোন অ্যারে বা অবজেক্ট করার সহজ উপায়:

var dup_array = JSON.parse(JSON.stringify(original_array))

56
নতুনদের জন্য গুরুত্বপূর্ণ নোট: কারণ এটি জেএসএনের উপর নির্ভর করে, এটিও এর সীমাবদ্ধতার উত্তরাধিকার সূত্রে আসে। অন্যান্য জিনিসগুলির মধ্যে, এর অর্থ হল আপনার অ্যারেতে undefinedকোনও functionউপাদান থাকতে পারে না । এই দুটিই প্রক্রিয়া nullচলাকালীন আপনার জন্য রূপান্তরিত হবে JSON.stringify। অন্যান্য কৌশল যেমন (['cool','array']).slice()তাদের পরিবর্তন করবে না তবে অ্যারের মধ্যে গভীর ক্লোন অবজেক্টগুলিও রাখবে না। সুতরাং একটি বাণিজ্য আছে।
শেঠ হল্লাদে

27
খুব খারাপ পারফেক্ট এবং DOM, তারিখ, regexp, ফাংশন ... বা প্রোটোটাইপযুক্ত বস্তুর মতো বিশেষ অবজেক্টের সাথে কাজ করবেন না। চক্রীয় রেফারেন্সগুলি সমর্থন করবেন না। গভীর ক্লোনের জন্য আপনার কখনই JSON ব্যবহার করা উচিত নয়।
ইউকুল্লি

17
সবচেয়ে খারাপ সম্ভাব্য উপায়! কেবলমাত্র যদি কোনও সমস্যার জন্য অন্য সমস্ত কাজ না করে তবেই ব্যবহার করুন। এটি ধীর গতির, এটি সম্পদের তীব্র এবং এতে ইতিমধ্যে মন্তব্যে উল্লিখিত সমস্ত জেএসএন সীমাবদ্ধতা রয়েছে। এটি কীভাবে 25 টি ভোট পেয়েছে তা কল্পনা করতে পারছি না।
লুকাস লিসিস

2
এটি আদিমগুলির সাথে অ্যারেগুলি অনুলিপি করে এবং যেখানে বৈশিষ্ট্যগুলি আরও প্রাথমিক / অ্যারে সহ অ্যারে হয়। তার জন্য এটি ঠিক আছে।
ড্রেনাই

4
আমি উপরের ড্যানের উত্তরের বিপরীতে আমার ব্রাউজারে (Chrome 59.0.3071.115) এটি পরীক্ষা করেছি। এটি .slice () এর চেয়ে প্রায় 20 গুণ কম ধীর ছিল। n = 1000*1000; start = + new Date(); a = Array(n); var b = JSON.parse(JSON.stringify(a)) console.log(new Date() - start); // 221
হ্যারি স্টিভেনস

29
var cloned_array = [].concat(target_array);

3
এটি কি করে দয়া করে ব্যাখ্যা করুন।
জেড ফক্স

8
যদিও এই কোড স্নিপেট প্রশ্নের উত্তর দিতে পারে, এটি কীভাবে বা কেন তা ব্যাখ্যা করার জন্য কোনও প্রসঙ্গ সরবরাহ করে না। আপনার উত্তরটি ব্যাখ্যা করতে একটি বা দুটি বাক্য যুক্ত করার বিষয়টি বিবেচনা করুন।
ব্র্যান্ডস্ক্রিপ্ট

32
আমি এই ধরনের মন্তব্য ঘৃণা করি। এটা কি এটা সুস্পষ্ট!
এসেসনেটসকেপ 21

6
একটি সাধারণ কাতারের জন্য একটি সহজ উত্তর, পড়ার জন্য কোনও বড় গল্প নেই। আমি উত্তর এই ধরনের +1 টি পছন্দ
সালে Achim

15
"আমি কেবল গতি সম্পর্কে জিজ্ঞাসা করছি" - এই উত্তরটি গতির কোনও ইঙ্গিত দেয় না। এটিই মূল প্রশ্ন করা হচ্ছে। ব্র্যান্ডস্ক্রিপ্ট একটি ভাল পয়েন্ট আছে। এটির উত্তর বিবেচনা করার জন্য আরও তথ্যের প্রয়োজন। তবে এটি যদি একটি সহজ প্রশ্ন ছিল তবে এটি একটি দুর্দান্ত উত্তর হবে।
TamusJRoyce

26

আমি একসাথে একটি দ্রুত ডেমো রেখেছি: http://jsbin.com/agugo3/edit

ইন্টারনেট এক্সপ্লোরার 8 এ আমার ফলাফলগুলি 156, 782 এবং 750, যা দেখায় sliceযে এই ক্ষেত্রে অনেক দ্রুত।


আপনার যদি খুব দ্রুত এই কাজটি করতে হয় তবে আবর্জনা সংগ্রহকারী অতিরিক্ত অতিরিক্ত ব্যয়টি ভুলে যাবেন না। আমি স্লাইস ব্যবহার করে আমার সেলুলার অটোম্যাটায় প্রতিটি প্রতিবেশীর অ্যারে অনুলিপি করছি এবং এটি আগের অ্যারে পুনরায় ব্যবহার করা এবং মানগুলি অনুলিপি করার চেয়ে অনেক ধীর ছিল। ক্রোম নির্দেশ করে যে মোট সময়ের প্রায় 40% সময় আবর্জনা সংগ্রহ করতে ব্যয় হয়েছিল।
drake7707

21

a.map(e => e)এই কাজের জন্য অন্য বিকল্প। আজকের .map()হিসাবে খুব দ্রুত (প্রায় হিসাবে দ্রুত.slice(0) ফায়ারফক্সে ) তবে ক্রোমে নেই।

অন্যদিকে, যদি একটি অ্যারের বহু মাত্রিক, কারণ অ্যারে বস্তু এবং বস্তুর রেফারেন্স ধরনের হয়, ফালি বা CONCAT পদ্ধতি কেউই একটি প্রতিকারও হতে হবে ... তাই একটি অ্যারের ক্লোনিং এক সঠিক ভাবে একটি উদ্ভাবন Array.prototype.clone()যেমন অনুসরণ করে।

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


খারাপ নয়, তবে দুর্ভাগ্যক্রমে এটি কাজ করে না যদি আপনার অ্যারেতে অবজেক্ট থাকে: S JSON.parse (JSON.stringify (myArray)) এই ক্ষেত্রে আরও ভাল কাজ করে।
জিবিম্যান

17

Ar অ্যারে ক্লোন করার দ্রুততম উপায়

অ্যারের ক্লোন করতে যে সময় লাগে তা পরীক্ষা করতে আমি এই খুব সাধারণ ইউটিলিটি ফাংশনটি তৈরি করেছি। এটি ১০০% নির্ভরযোগ্য নয় তবে এটি কোনও বিদ্যমান অ্যারের ক্লোন করতে কত সময় নেয় তা আপনাকে একটি বৃহত ধারণা দিতে পারে:

function clone(fn) {
    const arr = [...Array(1000000)];
    console.time('timer');
    fn(arr);
    console.timeEnd('timer');
}

এবং বিভিন্ন পদ্ধতির পরীক্ষিত:

1)   5.79ms -> clone(arr => Object.values(arr));
2)   7.23ms -> clone(arr => [].concat(arr));
3)   9.13ms -> clone(arr => arr.slice());
4)  24.04ms -> clone(arr => { const a = []; for (let val of arr) { a.push(val); } return a; });
5)  30.02ms -> clone(arr => [...arr]);
6)  39.72ms -> clone(arr => JSON.parse(JSON.stringify(arr)));
7)  99.80ms -> clone(arr => arr.map(i => i));
8) 259.29ms -> clone(arr => Object.assign([], arr));
9) Maximum call stack size exceeded -> clone(arr => Array.of(...arr));

আপডেট :
দ্রষ্টব্য: এগুলির মধ্যে, একটি অ্যারের গভীর ক্লোন করার একমাত্র উপায় হ'ল ব্যবহার JSON.parse(JSON.stringify(arr))

এটি বলেছিল, উপরেরটি ব্যবহার করবেন না যদি আপনার অ্যারেতে ফাংশন অন্তর্ভুক্ত থাকতে পারে কারণ এটি ফিরে আসবে null
এই আপডেটে জন্য আপনাকে @GilEpshtain ধন্যবাদ


2
আমি আপনার উত্তরটি বেঞ্চমার্ক করার চেষ্টা করেছি এবং আমি খুব আলাদা ফলাফল পেয়েছি: jsben.ch/o5nLG
mesqueeb

@ মেসেবিব, অবশ্যই আপনার মেশিনের উপর নির্ভর করে পরীক্ষাগুলি পরিবর্তন হতে পারে। তবে আপনার পরীক্ষার ফলাফলের সাথে উত্তরটি নির্দ্বিধায় আপডেট করুন। চমৎকার কাজ!
লাইয়ার এলরম

আমি আপনার উত্তরটি অনেক পছন্দ করি তবে আমি আপনার পরীক্ষাটি চেষ্টা করে দেখি এবং arr => arr.slice()এটি দ্রুততম।
গিল এপসেটে

1
@ লিয়ারএলরোম, পদ্ধতিগুলি সিরিয়ালযোগ্য নয় এই কারণে আপনার আপডেটটি সঠিক নয়। উদাহরণস্বরূপ: JSON.parse(JSON.stringify([function(){}]))আউটপুট হবে[null]
গিল এপসেটে

1
চমৎকার বেঞ্চমার্ক। আমি 2 ব্রাউজারে আমার ম্যাক এই পরীক্ষিত করেছি: ক্রোম সংস্করণ 81.0.4044.113 এবং সাফারি সংস্করণ 13.1 (15609.1.20.111.8) এবং দ্রুততম বিস্তার অপারেশন হল: [...arr]সঙ্গে 4.653076171875msChrome এ এবং 8.565msসাফারিতে। Chrome এ দ্বিতীয় ফাস্ট ফালি ফাংশন arr.slice()সঙ্গে 6.162109375msএবং সাফারিতে দ্বিতীয় [].concat(arr)সঙ্গে 13.018ms
এডুফিন

7

একবার দেখুন: লিঙ্ক । এটি গতির কথা নয়, স্বাচ্ছন্দ্যের কথা। এছাড়া হিসাবে আপনি দেখতে পারেন আপনি শুধুমাত্র ব্যবহার করতে পারেন ফালি (0) উপর আদিম ধরনের

এটির পুনর্বিবেচনার অনুলিপি না হয়ে অ্যারের স্বতন্ত্র অনুলিপি তৈরি করতে আপনি অ্যারের স্লাইস পদ্ধতিটি ব্যবহার করতে পারেন।

উদাহরণ:

এটির পুনর্বিবেচনার অনুলিপি না হয়ে অ্যারের স্বতন্ত্র অনুলিপি তৈরি করতে আপনি অ্যারের স্লাইস পদ্ধতিটি ব্যবহার করতে পারেন।

var oldArray = ["mip", "map", "mop"];
var newArray = oldArray.slice();

কোনও বিষয় অনুলিপি বা ক্লোন করতে:

function cloneObject(source) {
    for (i in source) {
        if (typeof source[i] == 'source') {
            this[i] = new cloneObject(source[i]);
        }
        else{
            this[i] = source[i];
  }
    }
}

var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'};
var obj2= new cloneObject(obj1);

সূত্র: লিংক


1
আদিম ধরনের মন্তব্য প্রযোজ্য forহিসাবে ভাল প্রশ্নে লুপ।
ব্যবহারকারী 113716

4
যদি আমি কোনও বস্তুর অ্যারে অনুলিপি করতাম তবে আমি আশা করব যে নতুন অ্যারেটি অবজেক্টগুলির ক্লোনিংয়ের পরিবর্তে একই জিনিসগুলিকে রেফারেন্স করবে।
লিঙ্কনঙ্ক

7

@ ড্যান যেমন বলেছিলেন "এই উত্তরটি পুরানো দ্রুত হয়ে যায় actual আসল পরিস্থিতি যাচাই করার জন্য মাপদণ্ড ব্যবহার করুন ", জেএসপিআফের একটি নির্দিষ্ট উত্তর রয়েছে যার নিজের উত্তর নেই: যখন :

var i = a.length;
while(i--) { b[i] = a[i]; }

রানারআপের সাথে 960,589 অপস / সেকেন্ড ছিল a.concat() ছিল 578,129 অপস / সেকেন্ড, যা 60%।

এটি সর্বশেষতম ফায়ারফক্স (40) 64 বিট।


@ আলেকারসন একটি নতুন, আরও নির্ভরযোগ্য বেঞ্চমার্ক তৈরি করেছেন।


1
আপনার সত্যই jsperf লিঙ্ক করা উচিত। আপনি যেটির কথা ভাবছেন তা ভেঙে গেছে, কারণ 'ওয়েল লুপ' পরীক্ষা ব্যতীত প্রতিটি পরীক্ষার ক্ষেত্রে একটি নতুন অ্যারে তৈরি করা হয়।
আলেকারসন

1
আমি একটি নতুন জেএসপিফ তৈরি করেছি যা আরও নিখুঁত: jsperf.com/clone-array-3
aleclarson

60% কি? 60% দ্রুত?
পিটার মর্টেনসেন

1
@PeterMortensen: 587192 ~ 960589. 60% (61.1 ...) হয়
serv-Inc

7

ECMAScript 2015 এর সাথে উপায় Spreadঅপারেটরের :

প্রাথমিক উদাহরণ:

var copyOfOldArray = [...oldArray]
var twoArraysBecomeOne = [...firstArray, ..seccondArray]

ব্রাউজার কনসোলে চেষ্টা করুন:

var oldArray = [1, 2, 3]
var copyOfOldArray = [...oldArray]
console.log(oldArray)
console.log(copyOfOldArray)

var firstArray = [5, 6, 7]
var seccondArray = ["a", "b", "c"]
var twoArraysBecomOne = [...firstArray, ...seccondArray]
console.log(twoArraysBecomOne);

তথ্যসূত্র


সম্ভবত স্প্রেডের সাথে দ্রুত কেবলমাত্র এটি টাইপ করা। এটি করার অন্যান্য পদ্ধতির তুলনায় এটি কম পারফর্মেন্ট।
এক্সT_নাভা

3
আপনার যুক্তি সম্পর্কে কিছু লিঙ্ক সরবরাহ করুন।
মারিয়ান ০7

6

এটি ব্রাউজারের উপর নির্ভর করে। আপনি যদি ব্লগ পোস্টে অ্যারে.প্রোটোটাইপ.স্লাইস বনাম ম্যানুয়াল অ্যারে তৈরির সন্ধান করেন তবে প্রত্যেকটির কার্য সম্পাদনের জন্য মোটামুটি গাইড রয়েছে:

এখানে চিত্র বিবরণ লিখুন

ফলাফল:

এখানে চিত্র বিবরণ লিখুন


1
argumentsকোনও সঠিক অ্যারে নয় এবং তিনি সংগ্রহটি চালানোর callজন্য চাপ প্রয়োগ sliceকরছেন। ফলাফল বিভ্রান্তিকর হতে পারে।
লিঙ্কনঙ্ক

হ্যাঁ আমি আমার পোস্টে উল্লেখ করতে চাইছিলাম যে ব্রোসওয়ারগুলির উন্নতি হওয়ার সাথে সাথে এই পরিসংখ্যানগুলি সম্ভবত এখন পরিবর্তিত হবে, তবে এটি একটি সাধারণ ধারণা দেয়।
কিন্ডিগগুলি

2
@diugalde আমি মনে করি যখন কোডটি সম্ভাব্য বিপজ্জনক এবং অনুলিপিযুক্ত করা উচিত নয় তখনই ছবি হিসাবে পোষ্ট কোড গ্রহণযোগ্য হয় situation এই ক্ষেত্রে যদিও, এটি বেশ হাস্যকর।
ফ্লোরিয়ান ওয়েনডেলবোন

6

অনেক ক্লিনার সমাধান রয়েছে:

var srcArray = [1, 2, 3];
var clonedArray = srcArray.length === 1 ? [srcArray[0]] : Array.apply(this, srcArray);

দৈর্ঘ্যের চেকটি প্রয়োজনীয়, কারণ Arrayযখন একে একে যুক্তি দিয়ে ডাকা হয় তখন কনস্ট্রাক্টর আলাদা আচরণ করে।


2
তবে এটি কি দ্রুততম?
ক্রিস ওয়েসলিং

14
splice()সম্ভবত এর চেয়ে বেশি শব্দার্থক । কিন্তু সত্যিই, প্রয়োগ এবং এই সব কিন্তু স্বজ্ঞাত।
মাইকেল পিফেল 26'14


3
আপনি Array.ofদৈর্ঘ্যটি ব্যবহার এবং উপেক্ষা করতে পারেন :Array.of.apply(Array, array)
ওরিওল

6

মনে রাখবেন .স্লাইস () দ্বি-মাত্রিক অ্যারেগুলির জন্য কাজ করবে না। আপনার এই মত একটি ফাংশন প্রয়োজন হবে:

function copy(array) {
  return array.map(function(arr) {
    return arr.slice();
  });
}

3
জাভাস্ক্রিপ্টে দ্বিমাত্রিক অ্যারে নেই। অ্যারে সম্বলিত কেবল অ্যারে রয়েছে। আপনি যা করার চেষ্টা করছেন তা হ'ল একটি অনুলিপি যা প্রশ্নের প্রয়োজন নেই।
অ্যালোসো

5

এটি অ্যারের দৈর্ঘ্যের উপর নির্ভর করে। অ্যারের দৈর্ঘ্য <= 1,000,000 হয়, sliceএবং concatপদ্ধতিগুলি প্রায় একই সময় নিচ্ছে। আপনি যখন আরও বিস্তৃত পরিসর দিন, তখন concatপদ্ধতিটি জিতে যায়।

উদাহরণস্বরূপ, এই কোডটি চেষ্টা করে দেখুন:

var original_array = [];
for(var i = 0; i < 10000000; i ++) {
    original_array.push( Math.floor(Math.random() * 1000000 + 1));
}

function a1() {
    var dup = [];
    var start = Date.now();
    dup = original_array.slice();
    var end = Date.now();
    console.log('slice method takes ' + (end - start) + ' ms');
}

function a2() {
    var dup = [];
    var start = Date.now();
    dup = original_array.concat([]);
    var end = Date.now();
    console.log('concat method takes ' + (end - start) + ' ms');
}

function a3() {
    var dup = [];
    var start = Date.now();
    for(var i = 0; i < original_array.length; i ++) {
        dup.push(original_array[i]);
    }
    var end = Date.now();
    console.log('for loop with push method takes ' + (end - start) + ' ms');
}

function a4() {
    var dup = [];
    var start = Date.now();
    for(var i = 0; i < original_array.length; i ++) {
        dup[i] = original_array[i];
    }
    var end = Date.now();
    console.log('for loop with = method takes ' + (end - start) + ' ms');
}

function a5() {
    var dup = new Array(original_array.length)
    var start = Date.now();
    for(var i = 0; i < original_array.length; i ++) {
        dup.push(original_array[i]);
    }
    var end = Date.now();
    console.log('for loop with = method and array constructor takes ' + (end - start) + ' ms');
}

a1();
a2();
a3();
a4();
a5();

আপনি যদি অরিজিনাল_রে এর দৈর্ঘ্যকে 1,000,000 তে সেট করেন তবে sliceপদ্ধতি এবংconcat পদ্ধতিটি প্রায় একই সময় নিচ্ছে (র্যান্ডম সংখ্যার উপর নির্ভর করে 3-4- এমএস)।

আপনি যদি অরিজিনাল-অ্যারেটির দৈর্ঘ্য 10,000,000 এ সেট করেন, তবে sliceপদ্ধতিটি 60 এমএসেরও বেশি সময় নেয় এবং concatপদ্ধতিটি 20 এমএসেরও বেশি সময় নেয়।


dup.pushভুল হয় a5, পরিবর্তে dup[i] = ব্যবহার করা উচিত
4esn0k


2
        const arr = ['1', '2', '3'];

         // Old way
        const cloneArr = arr.slice();

        // ES6 way
        const cloneArrES6 = [...arr];

// But problem with 3rd approach is that if you are using muti-dimensional 
 // array, then only first level is copied

        const nums = [
              [1, 2], 
              [10],
         ];

        const cloneNums = [...nums];

// Let's change the first item in the first nested item in our cloned array.

        cloneNums[0][0] = '8';

        console.log(cloneNums);
           // [ [ '8', 2 ], [ 10 ], [ 300 ] ]

        // NOOooo, the original is also affected
        console.log(nums);
          // [ [ '8', 2 ], [ 10 ], [ 300 ] ]

সুতরাং, এই পরিস্থিতিতেটি এড়াতে, ব্যবহার করুন

        const arr = ['1', '2', '3'];

        const cloneArr = Array.from(arr);

cloneNums[0][0]আপনার উদাহরণে পরিবর্তন কীভাবে পরিবর্তনের প্রচার করেছিল তা উল্লেখ করার পক্ষে এটি একটি বৈধ বিষয় nums[0][0]but তবে এটি কারণ কারণ nums[0][0]কার্যকরভাবে এমন একটি বস্তু যার cloneNumsস্প্রেড অপারেটর দ্বারা রেফারেন্স অনুলিপি করা হয়। কেবলমাত্র এটিই বলা যায়, এই আচরণটি কোডটি প্রভাবিত করে না যেখানে আমরা মান (ইন্টি, স্ট্রিং ইত্যাদি আক্ষরিক) দ্বারা অনুলিপি করছি।
আদিত্য এমপি

1

বেঞ্চমার্কের সময়!

function log(data) {
  document.getElementById("log").textContent += data + "\n";
}

benchmark = (() => {
  time_function = function(ms, f, num) {
    var z = 0;
    var t = new Date().getTime();
    for (z = 0;
      ((new Date().getTime() - t) < ms); z++)
      f(num);
    return (z)
  }

  function clone1(arr) {
    return arr.slice(0);
  }

  function clone2(arr) {
    return [...arr]
  }

  function clone3(arr) {
    return [].concat(arr);
  }

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

  function clone4(arr) {
    return arr.clone();
  }


  function benchmark() {
    function compare(a, b) {
      if (a[1] > b[1]) {
        return -1;
      }
      if (a[1] < b[1]) {
        return 1;
      }
      return 0;
    }

    funcs = [clone1, clone2, clone3, clone4];
    results = [];
    funcs.forEach((ff) => {
      console.log("Benchmarking: " + ff.name);
      var s = time_function(2500, ff, Array(1024));
      results.push([ff, s]);
      console.log("Score: " + s);

    })
    return results.sort(compare);
  }
  return benchmark;
})()
log("Starting benchmark...\n");
res = benchmark();

console.log("Winner: " + res[0][0].name + " !!!");
count = 1;
res.forEach((r) => {
  log((count++) + ". " + r[0].name + " score: " + Math.floor(10000 * r[1] / res[0][1]) / 100 + ((count == 2) ? "% *winner*" : "% speed of winner.") + " (" + Math.round(r[1] * 100) / 100 + ")");
});
log("\nWinner code:\n");
log(res[0][0].toString());
<textarea rows="50" cols="80" style="font-size: 16; resize:none; border: none;" id="log"></textarea>

আপনি বোতামটি ক্লিক করার পরে 10 দশক ধরে বেঞ্চমার্ক চলবে।

আমার ফলাফল:

ক্রোম (ভি 8 ইঞ্জিন):

1. clone1 score: 100% *winner* (4110764)
2. clone3 score: 74.32% speed of winner. (3055225)
3. clone2 score: 30.75% speed of winner. (1264182)
4. clone4 score: 21.96% speed of winner. (902929)

ফায়ারফক্স (স্পাইডারমোনকি ইঞ্জিন):

1. clone1 score: 100% *winner* (8448353)
2. clone3 score: 16.44% speed of winner. (1389241)
3. clone4 score: 5.69% speed of winner. (481162)
4. clone2 score: 2.27% speed of winner. (192433)

বিজয়ী কোড:

function clone1(arr) {
    return arr.slice(0);
}

বিজয়ী ইঞ্জিন:

স্পাইডারমোনকি (মজিলা / ফায়ারফক্স)


1

জাভাস্ক্রিপ্টে কোনও অ্যারের সদৃশ করার জন্য দ্রুত উপায়:

#1: array1copy = [...array1];

#2: array1copy = array1.slice(0);

#3: array1copy = array1.slice();

যদি আপনার অ্যারে অবজেক্টগুলিতে কিছু JSON- অ-সিরিয়ালাইজযোগ্য সামগ্রী (ফাংশন, সংখ্যা PPOSITIVE_INFINITY, ইত্যাদি) থাকে তবে ব্যবহার করা ভাল better

array1copy = JSON.parse(JSON.stringify(array1))


0

আপনি এই কোড অনুসরণ করতে পারেন। অপরিবর্তনীয় উপায় অ্যারের ক্লোন। অ্যারে ক্লোনিংয়ের এটি সঠিক উপায়


const array = [1, 2, 3, 4]

const newArray = [...array]
newArray.push(6)
console.log(array)
console.log(newArray)

0

ES6 এ, আপনি কেবল স্প্রেড সিনট্যাক্সটি ব্যবহার করতে পারেন

উদাহরণ:

let arr = ['a', 'b', 'c'];
let arr2 = [...arr];

দয়া করে নোট করুন যে স্প্রেড অপারেটর সম্পূর্ণ নতুন অ্যারে জেনারেট করে, সুতরাং কোনওটি পরিবর্তন করে অন্যটিকে প্রভাবিত করবে না।

উদাহরণ:

arr2.push('d') // becomes ['a', 'b', 'c', 'd']
console.log(arr) // while arr retains its values ['a', 'b', 'c']
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.