जावास्क्रिप्ट में एक सरणी को डुप्लिकेट करने का सबसे तेज़ तरीका - स्लाइस बनाम 'लूप' के लिए


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

मुझे पता है कि दोनों तरीके केवल एक उथली नकल करते हैं : अगर original_array में ऑब्जेक्ट्स के संदर्भ होते हैं, तो ऑब्जेक्ट क्लोन नहीं किए जाएंगे, लेकिन केवल संदर्भ कॉपी किए जाएंगे, और इसलिए दोनों सरणियों में समान ऑब्जेक्ट्स के संदर्भ होंगे। लेकिन यह इस सवाल का बिंदु नहीं है।

मैं केवल गति के बारे में पूछ रहा हूं।


3
jsben.ch/#/wQ9RU <= एक सरणी क्लोन करने के सबसे सामान्य तरीकों के लिए एक बेंचमार्क
एस्केपनेटस्केप

जवाबों:


776

किसी सरणी को क्लोन करने के कम से कम 5 (!) तरीके हैं:

  • पाश
  • टुकड़ा
  • Array.from ()
  • concat
  • प्रसार ऑपरेटर (फास्टेस्ट)

निम्नलिखित जानकारी प्रदान करने वाला एक ह्युगेन बेंचमार्क थ्रेड है :

  • के लिए झपकी ब्राउज़रों slice(), सबसे तेज तरीका है concat()थोड़ा धीमा है, और while loop2.4x धीमी है।

  • अन्य ब्राउज़रों while loopके लिए सबसे तेज़ तरीका है, क्योंकि उन ब्राउज़र में sliceऔर के लिए आंतरिक अनुकूलन नहीं हैं concat

यह बात जुल 2016 में सही बनी हुई है।

नीचे सरल स्क्रिप्ट हैं जो आप अपने ब्राउज़र के कंसोल में कॉपी-पेस्ट कर सकते हैं और चित्र को देखने के लिए कई बार चला सकते हैं। वे मिलीसेकंड का उत्पादन करते हैं, कम बेहतर है।

घुमाव के दौरान

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
Dan

2
@ तो क्या हो सकता है? आपका परीक्षण मामला परिणाम: फ़ायरफ़ॉक्स 30 रात्रि अभी भी क्रोम की तुलना में ~ 230% तेज है। V8 के स्रोत कोड की जांच करें spliceऔर आपको आश्चर्य होगा (जबकि ...)
mate64

4
छोटे सरणियों के लिए दुख की बात है कि इसका उत्तर बहुत अलग है । उदाहरण के लिए उनमें से प्रत्येक को कॉल करने से पहले श्रोताओं की एक सरणी क्लोनिंग। वे एरे अक्सर छोटे होते हैं, आमतौर पर 1 तत्व।
gman

6
आप इस विधि से चूक गए:A.map(function(e){return e;});
wcochran

13
आप ब्लिंक ब्राउज़र के बारे में लिख रहे हैं । नहीं है झपकी सिर्फ एक लेआउट इंजन, मुख्य रूप से HTML प्रतिपादन को प्रभावित करने, और इस तरह महत्वहीन? मैंने सोचा था कि हम यहाँ V8, स्पाइडरमैन और दोस्तों के बारे में बात करेंगे। बस एक चीज जिसने मुझे भ्रमित किया। अगर मैं गलत हूं तो मुझे बताएं।
नियॉनिट

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 तुम, बस सरणी के पिछले तत्व गिरा दिया है। पूर्ण प्रतिलिपि array.slice (0) या array.slice (0, array.length)
मारेक

137

es6 रास्ते के बारे में क्या?

arr2 = [...arr1];

23
अगर बबल के साथ परिवर्तित किया जाता है:[].concat(_slice.call(arguments))
CHAN

1
निश्चित नहीं है कि कहां argumentsसे आ रहा है ... मुझे लगता है कि आपका बेबल आउटपुट कुछ अलग विशेषताओं का सामना कर रहा है। यह होने की अधिक संभावना है arr2 = [].concat(arr1)
स्टर्लिंग आर्चर

3
@SterlingArcher इससे arr2 = [].conact(arr1)अलग है arr2 = [...arr1][...arr1]सिंटैक्स छेद को रूपांतरित करेगा undefined। उदाहरण के लिए, arr1 = Array(1); arr2 = [...arr1]; arr3 = [].concat(arr1); 0 in arr2 !== 0 in arr3
tsh

1
मैंने इसे अपने ब्राउज़र में (क्रोम 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
शुरुआती लोगों के लिए महत्वपूर्ण नोट: क्योंकि यह JSON पर निर्भर करता है, इसलिए यह अपनी सीमाएं भी प्राप्त करता है। अन्य बातों के अलावा, इसका मतलब है कि आपके सरणी में undefinedकोई भी सम्‍मिलित नहीं हो सकता है function। प्रक्रिया के nullदौरान उन दोनों को आपके लिए परिवर्तित किया जाएगा JSON.stringify। अन्य रणनीतियाँ, जैसे कि (['cool','array']).slice()उन्हें परिवर्तित नहीं करेंगी , लेकिन सरणी के भीतर गहरी क्लोन ऑब्जेक्ट भी नहीं। तो एक व्यापार है।
सेठ होलादाय

27
बहुत खराब पूर्ण और विशेष वस्तुओं जैसे कि DOM, date, regexp, function ... या प्रोटोटाइप ऑब्जेक्ट्स के साथ काम नहीं करते हैं। चक्रीय संदर्भों का समर्थन न करें। आपको गहरी क्लोन के लिए JSON का उपयोग कभी नहीं करना चाहिए।
युकुले

17
सबसे खराब तरीका! केवल उपयोग अगर कुछ मुद्दे के लिए अन्य सभी काम नहीं करता है। यह धीमा है, यह संसाधन गहन है और इसमें पहले से ही टिप्पणियों में उल्लिखित सभी JSON सीमाएँ हैं। सोच भी नहीं सकते कि उसे 25 वोट कैसे मिले।
लुकास एलिस

2
यह प्राथमिकताओं के साथ सरणियों की गहरी प्रतियां बनाता है, और जहां गुण आगे आदिम / सरणियों के साथ सरणियां हैं। उसके लिए यह ठीक है।
Drenai

4
मैंने इसे अपने ब्राउज़र में (क्रोम 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
मुझे इस तरह की टिप्पणियों से नफरत है। यह स्पष्ट है कि यह क्या करता है!
एस्केपनेटस्केप

6
एक साधारण प्रश्न के लिए एक सरल उत्तर, पढ़ने के लिए कोई बड़ी कहानी नहीं। मुझे इस तरह के जवाब पसंद हैं +1
अचिम

15
"मैं केवल गति के बारे में पूछ रहा हूं" - यह उत्तर गति पर कोई संकेत नहीं देता है। यही मुख्य प्रश्न पूछा जा रहा है। ब्रॉन्डस्क्रिप्ट में एक अच्छा बिंदु है। इस उत्तर पर विचार करने के लिए अधिक जानकारी की आवश्यकता है। लेकिन अगर यह एक सरल प्रश्न था, तो यह एक उत्कृष्ट उत्तर होगा।
तमसुराजॉय

26

मैंने एक त्वरित डेमो एक साथ रखा: http://jsbin.com/agugo3/edit

Internet Explorer 8 पर मेरे परिणाम 156, 782, और 750 हैं, जो इंगित करेगा कि sliceइस मामले में बहुत तेज है।


अगर आपको यह बहुत तेजी से करना है तो कूड़ा उठाने वाले की अतिरिक्त लागत को न भूलें। मैं अपने सेल्यूलर ऑटोमेटा में प्रत्येक सेल के लिए प्रत्येक पड़ोसी सरणी की प्रतिलिपि स्लाइस का उपयोग कर रहा था और यह पिछले सरणी का पुन: उपयोग करने और मूल्यों की प्रतिलिपि बनाने की तुलना में बहुत धीमी थी। क्रोम ने संकेत दिया कि कुल समय का लगभग 40% कचरा एकत्र करने में खर्च किया गया था।
drake7707

21

a.map(e => e)इस नौकरी के लिए एक और विकल्प है। आज के समय में फ़ायरफ़ॉक्स में .map()बहुत तेज़ (लगभग उतना ही तेज़ .slice(0)) है, लेकिन क्रोम में नहीं है।

दूसरी ओर, यदि कोई सरणी बहु-आयामी है, क्योंकि सरणियाँ ऑब्जेक्ट हैं और ऑब्जेक्ट संदर्भ प्रकार हैं, तो स्लाइस या कॉनैट तरीकों में से कोई भी एक इलाज नहीं होगा ... इसलिए किसी सरणी को क्लोन करने का एक उचित तरीका के 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));


बुरा नहीं है, लेकिन दुर्भाग्य से यह आपके सरणी में वस्तु होने पर काम नहीं करता है: \ JSON.parse (JSON.stringify (myArray)) इस मामले में बेहतर काम करता है।
जीबीएमएन

17

। सबसे तेज रास्ता क्लोन करने के लिए एक सरणी

मैंने एक सरणी क्लोन करने के लिए लगने वाले समय का परीक्षण करने के लिए यह बहुत सादा उपयोगिता फ़ंक्शन बनाया। यह 100% विश्वसनीय नहीं है, लेकिन यह आपको एक थोक विचार दे सकता है क्योंकि मौजूदा सरणी को क्लोन करने में कितना समय लगता है:

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

@mesqueeb, पाठ्यक्रम की उर मशीन के आधार पर परीक्षण बदल सकते हैं। हालांकि, अपने परीक्षा परिणाम के साथ उत्तर को अपडेट करने के लिए स्वतंत्र महसूस करें। अच्छा काम!
लायर एलरोम

मुझे आपका उत्तर बहुत पसंद है, हालांकि मैं आपके परीक्षण की कोशिश करता हूं और प्राप्त करता हूं कि arr => arr.slice()यह सबसे तेज है।
गिल एप्सटेन

1
@LiorElrom, इस तथ्य के कारण आपका अद्यतन सही नहीं है, क्योंकि विधियाँ क्रमबद्ध नहीं हैं। उदाहरण के लिए: JSON.parse(JSON.stringify([function(){}]))आउटपुट[null]
गिल एप्सटेन

1
अच्छा बेंचमार्क। मैं 2 ब्राउज़रों में अपने Mac पर इस परीक्षण किया है: क्रोम संस्करण 81.0.4044.113 और सफारी संस्करण 13.1 (15609.1.20.111.8) और सबसे तेजी से प्रसार के ऑपरेशन है: [...arr]के साथ 4.653076171875msक्रोम में और 8.565msसफारी में। क्रोम में दूसरा तेजी से टुकड़ा समारोह है 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और साथ ही सवाल में पाश।
user113716

4
अगर मैं वस्तुओं की एक सरणी की प्रतिलिपि बना रहा था, तो मैं नए सरणी से वस्तुओं को क्लोन करने के बजाय उसी वस्तुओं को संदर्भित करने की अपेक्षा करूंगा।
lincolnk

7

जैसा कि @Dan ने कहा "यह उत्तर तेजी से पुराना हो गया है। वास्तविक स्थिति की जाँच करने के लिए बेंचमार्क का उपयोग करें ", jsperf का एक विशिष्ट उत्तर है जिसका स्वयं के लिए कोई उत्तर नहीं है: जबकि :

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

रनरअप के साथ 960,589 ऑप्स / सेकेंड थे a.concat() साथ 960,589 ऑप्स / सेकंड था, जो 60% है।

यह सबसे अंतिम फ़ायरफ़ॉक्स (40) 64 बिट है।


@aleclarson ने एक नया, अधिक विश्वसनीय बेंचमार्क बनाया।


1
आपको वास्तव में jsperf को लिंक करना चाहिए। जिसे आप सोच रहे हैं वह टूट गया है, क्योंकि 'लूप' टेस्ट को छोड़कर हर टेस्ट केस में एक नया एरे बनाया जाता है।
एलेक्लेरसन

1
मैंने एक नया jsperf बनाया जो अधिक सटीक है: jsperf.com/clone-array-3
aleclarson

60% क्या? 60% तेज?
पीटर मोर्टेनसेन

1
@PeterMortensen: 587192 ~ 60% (61.1 ...) का 960589 है।
सर्व-इंक

7

Spreadऑपरेटर के साथ ECMAScript 2015 का तरीका :

मूल उदाहरण:

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

संदर्भ


शायद केवल एक चीज जो प्रसार के साथ तेज है, उसे टाइप करना है। यह ऐसा करने के अन्य तरीकों की तुलना में वाया कम प्रदर्शनकारी है।
XT_Nova

3
कृपया अपने तर्क के बारे में कुछ लिंक प्रदान करें।
मरिअन ०

6

यह ब्राउज़र पर निर्भर करता है। यदि आप ब्लॉग पोस्ट Array.prototype.slice बनाम मैनुअल सरणी निर्माण में देखते हैं , तो प्रत्येक के प्रदर्शन के लिए एक मोटा गाइड है:

यहां छवि विवरण दर्ज करें

परिणाम:

यहां छवि विवरण दर्ज करें


1
argumentsएक उचित सरणी नहीं है और वह संग्रह पर चलने के callलिए मजबूर sliceकरने के लिए उपयोग कर रहा है । परिणाम भ्रामक हो सकते हैं।
lincolnk

हां, मेरा मतलब अपनी पोस्ट में यह बताना था कि ये आँकड़े शायद अब सुधार करने वाले ब्रदर्स के साथ बदल जाएंगे, लेकिन यह एक सामान्य विचार देता है।
किंडिग्स

2
@diugalde मुझे लगता है कि एक ही स्थिति है जहां एक तस्वीर के रूप में कोड पोस्ट करना स्वीकार्य है, जब कोड संभावित रूप से खतरनाक है और कॉपी-पेस्ट नहीं किया जाना चाहिए। इस मामले में हालांकि, यह काफी हास्यास्पद है।
फ्लोरियन वेंडेलबोर्न

6

एक बहुत क्लीनर समाधान है:

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

लंबाई की जांच की आवश्यकता होती है, क्योंकि Arrayनिर्माणकर्ता अलग तरीके से व्यवहार करता है जब इसे ठीक एक तर्क के साथ कहा जाता है।


2
लेकिन क्या यह सबसे तेज है?
क्रिस वेसलिंग

14
से अधिक शब्दार्थ splice(), शायद। लेकिन वास्तव में, लागू करें और यह सब सहज है।
माइकल पिफेल

शो पर धीमी प्रदर्शन क्रोम jsperf.com/new-array-vs-splice-vs-slice/113
chrismarx

3
आप Array.ofलंबाई का उपयोग कर सकते हैं और उसकी अनदेखी कर सकते हैं :Array.of.apply(Array, array)
ओरिओल

6

याद रखें .slice () द्वि-आयामी सरणियों के लिए काम नहीं करेगा। आप इस तरह एक समारोह की आवश्यकता होगी:

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

यदि आप original_array की लंबाई को 1,000,000 पर सेट करते हैं, तो sliceविधि औरconcat विधि लगभग एक ही समय (3-4 ms, यादृच्छिक संख्या के आधार पर) ले रहे हैं।

यदि आप original_array की लंबाई 10,000,000 निर्धारित करते हैं, तो sliceविधि 60 ms से अधिक है और concatविधि 20 ms से अधिक लेती है।


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]- लेकिन ऐसा इसलिए है क्योंकि nums[0][0]प्रभावी रूप से एक वस्तु है जिसका संदर्भ cloneNumsप्रसार ऑपरेटर द्वारा कॉपी किया गया है। यह सब कहना है, यह व्यवहार उस कोड को प्रभावित नहीं करेगा जहां हम मूल्य (int, string आदि शाब्दिक) की नकल कर रहे हैं।
आदित्य सांसद

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>

बटन क्लिक करने के बाद बेंचमार्क 10s तक चलेगा।

मेरे परिणाम:

क्रोम (V8 इंजन):

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-non-serializable सामग्री (फ़ंक्शन, Number.POSITIVE_INFINITY, आदि) का उपयोग करना बेहतर है।

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']
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.