आप मूल सरणी को म्यूट किए बिना किसी सरणी को कैसे सॉर्ट कर सकते हैं?


230

मान लीजिए कि मुझे एक प्रकार का फ़ंक्शन चाहिए था जो इनपुट किए गए सरणी की एक क्रमबद्ध प्रतिलिपि देता है। मैंने भोलेपन से यह कोशिश की

function sort(arr) {
  return arr.sort();
}

और मैंने इसे इसके साथ परीक्षण किया, जिससे पता चलता है कि मेरी sortविधि सरणी को बदल रही है।

var a = [2,3,7,5,3,7,1,3,4];
sort(a);
alert(a);  //alerts "1,2,3,3,3,4,5,7,7"

मैंने भी इस दृष्टिकोण की कोशिश की

function sort(arr) {
  return Array.prototype.sort(arr);
}

लेकिन यह बिल्कुल काम नहीं करता है।

क्या इसके आस-पास एक सीधा रास्ता है, अधिमानतः एक ऐसा तरीका है जिसके लिए मेरे स्वयं के सॉर्टिंग एल्गोरिदम को हाथ से रोलिंग करने या सरणी के हर तत्व को एक नए में कॉपी करने की आवश्यकता नहीं है?


1
सरणी की एक गहरी प्रतिलिपि बनाएँ और इसके बजाय इसे सॉर्ट करें।
evanmcdonnal

1
@evanmcdonnal एक उथली प्रतिलिपि काफी अच्छी हो सकती है अगर सभी चाहते हैं कि वह पुनः व्यवस्थित हो और सरणी में प्रत्येक आइटम का डुप्लिकेट न हो।
काकोआ

.sortthisसरणी होने के लिए मान की आवश्यकता होती है , इसलिए अंतिम स्निपेट के लिए आपको काम करना होगा .sort.call(arr)(हालांकि यह आपकी समस्या को हल नहीं करता है)।
pimvdb

@Kekoa हाँ यह एक अच्छी बात है। यदि आप केवल तत्वों के क्रम को बदलने जा रहे हैं और स्वयं तत्वों को नहीं, तो अधिक मेमोरी का उपभोग करने की आवश्यकता नहीं है।
evanmcdonnal

zzzzBov की विधि एक आकर्षण की तरह काम कर रही है! stackoverflow.com/a/9592774/7011860
समेट एम।

जवाबों:


222

बस सरणी की प्रतिलिपि बनाएँ। ऐसा करने के कई तरीके हैं:

function sort(arr) {
  return arr.concat().sort();
}

// Or:
return Array.prototype.slice.call(arr).sort(); // For array-like objects

2
क्या यह एक गहरी प्रतिलिपि करेगा, अर्थात, नेस्टेड ऑब्जेक्ट्स और सरणियों को भी कॉपी किया जाएगा?
पीटर ओल्सन

2
वहाँ concatकहने का उपयोग करने के लिए कोई फायदा है slice(0)या वे सभी बहुत ज्यादा एक ही हैं?
जारेपपार

3
@PeterOlson नहीं, यह एक उथली प्रति है। यदि आप वास्तव में एक गहरी प्रतिलिपि चाहते हैं, तो इसके लिए मौजूदा उत्कृष्ट उत्तरों को खोजने के लिए स्टैक ओवरफ्लो पर खोज सुविधा का उपयोग करें।
रॉब डब्ल्यू

11
स्लाइस अब उल्लेखनीय रूप से तेज़ बताया गया है
ज़ेंडर ब्राउन

3
Array.prototype.slice.call(arr).sort();इसके बजाय क्यों arr.slice().sort();?
ओलिवियर बोइस


61

निम्नलिखित का प्रयास करें

function sortCopy(arr) { 
  return arr.slice(0).sort();
}

slice(0)अभिव्यक्ति तत्व 0 पर सरणी शुरुआती एक कॉपी बन जाती।


32

आप सरणी की प्रतिलिपि बनाने के लिए बिना किसी तर्क के स्लाइस का उपयोग कर सकते हैं:

var foo,
    bar;
foo = [3,1,2];
bar = foo.slice().sort();

यह जवाब बहुत बढ़िया है! मुझे आश्चर्य है कि जावास्क्रिप्ट इस डिग्री के लिए उत्परिवर्तन की अनुमति देता है। गलत लगता है। एक बार फिर धन्यवाद।

12

आप यह भी कर सकते हैं

d = [20, 30, 10]
e = Array.from(d)
e.sort()

इस तरह d को म्यूट नहीं किया जाएगा।

function sorted(arr) {
  temp = Array.from(arr)
  return temp.sort()
}

//Use it like this
x = [20, 10, 100]
console.log(sorted(x))

यह उत्तर अच्छा है
लीसे

1

जो कोई भी एक गहरी प्रतिलिपि करना चाहता है (जैसे यदि आपके सरणी में ऑब्जेक्ट हैं) का उपयोग कर सकते हैं:

let arrCopy = JSON.parse(JSON.stringify(arr))

फिर आप arrCopyबिना बदले भी छांट सकते हैं arr

arrCopy.sort((obj1, obj2) => obj1.id > obj2.id)

कृपया ध्यान दें: यह बहुत बड़ी सरणियों के लिए धीमा हो सकता है।


यह आपके दूसरे उदाहरण के -बजाय काम करेगा >
पूतज़को

0

मैं अपनी अधिकांश प्रतियों के लिए Object.assign () का उपयोग करता हूं:

var copyArray = Object.assign([], originalArray).sort();

हालांकि, ओपी टिप्पणियों के माध्यम से देखने के बाद, मैंने थोड़ी गहरी नकल पर शोध किया और ऑब्जेक्ट का पता लगाया। असाइनमेंट न केवल एक उथले कॉपी करता है, बल्कि केवल गणना योग्य और स्वयं के गुणों का चयन करता है (जैसा कि इस पोस्ट में उत्तर दिया गया है )।

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