दिलचस्प पोस्ट
अलग-अलग कार्यों के अलग-अलग पते हैं? स्क्रॉल करने पर, संभवतः जावास्क्रिप्ट और सीएसएस का उपयोग करते हुए मैं पहली पंक्ति और तालिका का पहला कॉलम कैसे लॉक कर सकता हूं? .NET 4.0 में, मैं 'सैंडबॉक्स' कैसे एक इन-मेमोरी असेंबली करता हूं और एक विधि निष्पादित करता हूं? सभी 4 दिशाओं में कड़ी चोट की पहचान कैसे करें स्ट्रिंग इन जावा में एक पूरे शब्द कैसे खोजें अंगुल्य 2 मार्गों में हल करने का उपयोग करना एक रीजेक्स चरित्र ब्रैकेट में एक हाइफ़न भी शामिल है? LINQ – पूर्ण बाहरी सम्मिलित हों हस्ताक्षरित / अहस्ताक्षरित चार में अंतर Safari में jQuery के साथ पृष्ठ ज़ूम परिवर्तन का पता लगाएं माता-पिता को प्राप्त करें। location.url – iframe – बच्चे से माता-पिता के पास सभी चर एक गोले से दूसरे में पास करें? आप एक छवि दृश्य के लिए LayoutParams () कैसे सेट करते हैं? विंडो को बंद करने के दौरान चलाने के लिए एक कार्य शेड्यूल कैसे करें अजगर में, जब एक शब्दकोश, सूची या सेट का उपयोग करें?

जावास्क्रिप्ट में तेजी से स्थिर सॉर्टिंग एल्गोरिथ्म कार्यान्वयन

मैं लगभग 200-300 ऑब्जेक्ट्स की एक सरणी सॉर्ट करने के लिए देख रहा हूं, एक विशिष्ट कुंजी और एक दिए गए ऑर्डर (एसीसी / डेरा) पर छाँटें। परिणामों का क्रम लगातार और स्थिर होना चाहिए।

उपयोग करने के लिए सबसे अच्छा एल्गोरिथ्म क्या होगा, और क्या आप जावास्क्रिप्ट में इसके कार्यान्वयन का एक उदाहरण प्रदान कर सकते हैं?

धन्यवाद!

वेब के समाधान से एकत्रित समाधान "जावास्क्रिप्ट में तेजी से स्थिर सॉर्टिंग एल्गोरिथ्म कार्यान्वयन"

गैर-स्थिर सॉर्ट फ़ंक्शन से स्थिर सॉर्टिंग प्राप्त करना संभव है।

सॉर्ट करने से पहले आपको सभी तत्वों की स्थिति मिलती है। आपकी तरह की स्थिति में, यदि दोनों तत्व समान हैं, तो आप स्थिति के आधार पर सॉर्ट करें

टाडा! आपको एक स्थिर सॉर्ट मिला है

यदि आप इस तकनीक के बारे में अधिक जानना चाहते हैं और इसे कैसे लागू किया जाए तो मैंने इसके बारे में अपने ब्लॉग पर एक लेख लिखा है: http://blog.vjeux.com/2010/javascript/javascript-sorting-table.html

चूंकि आप कुछ स्थिर के लिए देख रहे हैं, मर्ज सॉर्ट करना चाहिए।

http://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-merge-sort/

कोड उपरोक्त वेबसाइट पर पाया जा सकता है:

function mergeSort(arr) { if (arr.length < 2) return arr; var middle = parseInt(arr.length / 2); var left = arr.slice(0, middle); var right = arr.slice(middle, arr.length); return merge(mergeSort(left), mergeSort(right)); } function merge(left, right) { var result = []; while (left.length && right.length) { if (left[0] <= right[0]) { result.push(left.shift()); } else { result.push(right.shift()); } } while (left.length) result.push(left.shift()); while (right.length) result.push(right.shift()); return result; } 

संपादित करें:

इस पोस्ट के मुताबिक, यह अर्रे जैसा दिखता है। कुछ कार्यान्वयन में मर्ज एक मर्ज सॉर्ट का उपयोग करता है।

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

यह आपको सामान्य Array.sort कार्यान्वयन जैसी अपनी तुलनात्मक फ़ंक्शन निर्दिष्ट करने की अनुमति देता है

कार्यान्वयन

 // Add stable merge sort to Array and jQuery prototypes // Note: We wrap it in a closure so it doesn't pollute the global // namespace, but we don't put it in $(document).ready, since it's // not dependent on the DOM (function() { // expose to Array and jQuery Array.prototype.mergeSort = jQuery.fn.mergeSort = mergeSort; function mergeSort(compare) { var length = this.length, middle = Math.floor(length / 2); if (!compare) { compare = function(left, right) { if (left < right) return -1; if (left == right) return 0; else return 1; }; } if (length < 2) return this; return merge( this.slice(0, middle).mergeSort(compare), this.slice(middle, length).mergeSort(compare), compare ); } function merge(left, right, compare) { var result = []; while (left.length > 0 || right.length > 0) { if (left.length > 0 && right.length > 0) { if (compare(left[0], right[0]) <= 0) { result.push(left[0]); left = left.slice(1); } else { result.push(right[0]); right = right.slice(1); } } else if (left.length > 0) { result.push(left[0]); left = left.slice(1); } else if (right.length > 0) { result.push(right[0]); right = right.slice(1); } } return result; } })(); 

उदाहरण उपयोग

 var sorted = [ 'Finger', 'Sandwich', 'sandwich', '5 pork rinds', 'a guy named Steve', 'some noodles', 'mops and brooms', 'Potato Chip Brand® chips' ].mergeSort(function(left, right) { lval = left.toLowerCase(); rval = right.toLowerCase(); console.log(lval, rval); if (lval < rval) return -1; else if (lval == rval) return 0; else return 1; }); sorted == ["5 pork rinds", "a guy named Steve", "Finger", "mops and brooms", "Potato Chip Brand® chips", "Sandwich", "sandwich", "some noodles"]; 

इस उत्तर में किए गए दावे के आधार पर, आप मूल कार्यान्वयन की परवाह किए बिना एक स्थिर सॉर्ट को लागू करने के लिए निम्न पॉलिफ़िल का उपयोग कर सकते हैं:

 // ECMAScript 5 polyfill Object.defineProperty(Array.prototype, 'stableSort', { configurable: true, writable: true, value: function stableSort (compareFunction) { 'use strict' var length = this.length var entries = Array(length) var index // wrap values with initial indices for (index = 0; index < length; index++) { entries[index] = [index, this[index]] } // sort with fallback based on initial indices entries.sort(function (a, b) { var comparison = Number(this(a[1], b[1])) return comparison || a[0] - b[0] }.bind(compareFunction)) // re-map original array to stable sorted values for (index = 0; index < length; index++) { this[index] = entries[index][1] } return this } }) // usage const array = Array(500000).fill().map(() => Number(Math.random().toFixed(4))) const alwaysEqual = () => 0 const isUnmoved = (value, index) => value === array[index] // not guaranteed to be stable console.log('sort() stable?', array .slice() .sort(alwaysEqual) .every(isUnmoved) ) // guaranteed to be stable console.log('stableSort() stable?', array .slice() .stableSort(alwaysEqual) .every(isUnmoved) ) // performance using realistic scenario with unsorted big data function time(arrayCopy, algorithm, compare) { var start var stop start = performance.now() algorithm.call(arrayCopy, compare) stop = performance.now() return stop - start } const ascending = (a, b) => a - b const msSort = time(array.slice(), Array.prototype.sort, ascending) const msStableSort = time(array.slice(), Array.prototype.stableSort, ascending) console.log('sort()', msSort.toFixed(3), 'ms') console.log('stableSort()', msStableSort.toFixed(3), 'ms') console.log('sort() / stableSort()', (100 * msSort / msStableSort).toFixed(3) + '%') 

यहाँ एक स्थिर कार्यान्वयन है यह मूल प्रकार का उपयोग करके काम करता है, लेकिन ऐसे मामलों में जहां तत्व समान के बराबर होते हैं, आप मूल अनुक्रमणिका स्थिति का उपयोग करके संबंधों को तोड़ते हैं।

 function stableSort(arr, cmpFunc) { //wrap the arr elements in wrapper objects, so we can associate them with their origional starting index position var arrOfWrapper = arr.map(function(elem, idx){ return {elem: elem, idx: idx}; }); //sort the wrappers, breaking sorting ties by using their elements orig index position arrOfWrapper.sort(function(wrapperA, wrapperB){ var cmpDiff = cmpFunc(wrapperA.elem, wrapperB.elem); return cmpDiff === 0 ? wrapperA.idx - wrapperB.idx : cmpDiff; }); //unwrap and return the elements return arrOfWrapper.map(function(wrapper){ return wrapper.elem; }); } 

एक गहन परीक्षण

 var res = stableSort([{a:1, b:4}, {a:1, b:5}], function(a, b){ return aa - ba; }); console.log(res); 

एक और जवाब का हवाला देते हुए, लेकिन तह कोडज़ पोस्ट नहीं किया।

लेकिन, यह मेरे बेंचमार्क के अनुसार उपवास नहीं है मैंने कस्टम तुलनित्र समारोह को स्वीकार करने के लिए एक मर्ज सॉर्ट इम्प्रेशन को संशोधित किया, और यह बहुत तेज था।

आप टाइम्सर्ट का उपयोग भी कर सकते हैं:

जीपीएल 3 जावास्क्रिप्ट कार्यान्वयन Array.prototype.timsort के रूप में पैक किया गया जावा कोड का एक सटीक पुनर्लेखन प्रतीत होता है

सार्वजनिक डोमेन कार्यान्वयन एक ट्यूटोरियल के तौर पर इसका मतलब है, नमूना कोड केवल इसका उपयोग पूर्णांक के साथ दिखाता है

टिमसॉर्ट, विलय और फेरबदल सॉर्ट का अत्यधिक अनुकूलित संकर है और पायथन में और जावा (1.7+) में डिफ़ॉल्ट सॉर्टिंग एल्गोरिदम है। यह एक जटिल एल्गोरिथम है, क्योंकि यह कई विशेष मामलों के लिए अलग एल्गोरिदम का उपयोग करता है। लेकिन इसके परिणामस्वरूप यह कई परिस्थितियों के तहत बहुत तेज है देखें: https://en.wikipedia.org/wiki/Timsort

गिनती सॉर्ट मर्ज सॉर्ट से भी तेज है (यह ओ (एन) समय में करता है) और यह पूर्णांक पर उपयोग के लिए है।

 Math.counting_sort = function (m) { var i var j var k var step var start var Output var hash k = m.length Output = new Array () hash = new Array () // start at lowest possible value of m start = 0 step = 1 // hash all values i = 0 while ( i < k ) { var _m = m[i] hash [_m] = _m i = i + 1 } i = 0 j = start // find all elements within x while ( i < k ) { while ( j != hash[j] ) { j = j + step } Output [i] = j i = i + 1 j = j + step } return Output } 

उदाहरण:

 var uArray = new Array ()<br/> var sArray = new Array ()<br/><br/> uArray = [ 10,1,9,2,8,3,7,4,6,5 ]<br/> sArray = Math.counting_sort ( uArray ) // returns a sorted array 

http://www.stoimen.com/blog/2010/07/02/friday-algorithms-javascript-marge-sort/ से एक सरल एक विलय

 var a = [34, 203, 3, 746, 200, 984, 198, 764, 9]; function mergeSort(arr) { if (arr.length < 2) return arr; var middle = parseInt(arr.length / 2); var left = arr.slice(0, middle); var right = arr.slice(middle, arr.length); return merge(mergeSort(left), mergeSort(right)); } function merge(left, right) { var result = []; while (left.length && right.length) { if (left[0] <= right[0]) { result.push(left.shift()); } else { result.push(right.shift()); } } while (left.length) result.push(left.shift()); while (right.length) result.push(right.shift()); return result; } console.log(mergeSort(a)); 

मुझे बहुआयामी arrays को एक मनमाने ढंग से कॉलम से सॉर्ट करना होगा, और फिर एक और मैं सॉर्ट करने के लिए इस फ़ंक्शन का उपयोग करता हूं:

 function sortMDArrayByColumn(ary, sortColumn){ //Adds a sequential number to each row of the array //This is the part that adds stability to the sort for(var x=0; x<ary.length; x++){ary[x].index = x;} ary.sort(function(a,b){ if(a[sortColumn]>b[sortColumn]){return 1;} if(a[sortColumn]<b[sortColumn]){return -1;} if(a.index>b.index){ return 1; } return -1; }); } 

ध्यान दें कि ary.sort कभी शून्य नहीं देता है, जहां पर "सॉर्ट" समारोह के कुछ कार्यान्वयन निर्णय लेते हैं जो सही नहीं हो सकते।

यह बहुत तेज़ है, भी है।

यहां बताया गया है कि कैसे आप मेजर सॉर्ट का उपयोग करने वाले प्रोटोटाइप विधि के साथ जेएस डिफ़ॉल्ट एरे ऑब्जेक्ट का विस्तार कर सकते हैं। यह विधि किसी विशिष्ट कुंजी (प्रथम पैरामीटर) को सॉर्ट करने और किसी दिए गए ऑर्डर ('एसीसी' / 'डे' को दूसरे पैरामीटर के रूप में) के लिए अनुमति देता है

 Array.prototype.mergeSort = function(sortKey, direction){ var unsortedArray = this; if(unsortedArray.length < 2) return unsortedArray; var middle = Math.floor(unsortedArray.length/2); var leftSubArray = unsortedArray.slice(0,middle).mergeSort(sortKey, direction); var rightSubArray = unsortedArray.slice(middle).mergeSort(sortKey, direction); var sortedArray = merge(leftSubArray, rightSubArray); return sortedArray; function merge(left, right) { var combined = []; while(left.length>0 && right.length>0){ var leftValue = (sortKey ? left[0][sortKey] : left[0]); var rightValue = (sortKey ? right[0][sortKey] : right[0]); combined.push((direction === 'desc' ? leftValue > rightValue : leftValue < rightValue) ? left.shift() : right.shift()) } return combined.concat(left.length ? left : right) } } 

इसलिए मुझे अपने रिएक्ट + रेडयुक्स ऐप के लिए एक स्थिर प्रकार की जरूरत थी, और वीजेक्स के जवाब में मेरी मदद की हालांकि, मेरा (जेनेरिक) समाधान अन्य लोगों की तुलना में अलग दिखता है जो मैं यहां तक ​​देख रहा हूं, इसलिए मैं इसे साझा कर रहा हूं अगर किसी और के पास मेल खाने वाला उपयोग-मामले होता है:

  • मैं वास्तव में sort() एपीआई के समान कुछ करना चाहता हूं, जहां मैं तुलनित्र फ़ंक्शन को पार कर सकता हूं।
  • कभी-कभी मैं कभी-कभी सॉर्ट कर सकता हूं, और कभी-कभी मेरा डेटा अपरिवर्तनीय होता है (क्योंकि रेड्यूक्स) और मुझे इसकी बजाय सॉर्ट की गई प्रतिलिपि की आवश्यकता होती है इसलिए प्रत्येक उपयोग-केस के लिए मुझे एक स्थिर सॉर्टिंग फ़ंक्शन की आवश्यकता है।
  • ES2015।

मेरा समाधान indices का एक टाइप किए गए सरणी बनाना है, फिर टू-सॉर्ट किए गए सरणी के आधार पर इन इंडेक्सों को सॉर्ट करने के लिए एक तुलना फंक्शन का उपयोग करें। फिर हम सॉर्ट किए गए indices का उपयोग मूल सरणी को या तो एक पास में एक सॉर्ट की गई प्रति बना सकते हैं। यदि वह भ्रमित है, तो इसे इस तरह से सोचें: जहां आप आम तौर पर तुलनात्मक फ़ंक्शन की तरह पारित करेंगे:

 (a, b) => { /* some way to compare a and b, returning -1, 0, or 1 */ }; 

अब आप इसका उपयोग करते हैं:

 (i, j) => { let a = arrayToBeSorted[i], b = arrayToBeSorted[j]; /* some way to compare a and b, returning -1 or 1 */ return i - j; // fallback when a == b } 

स्पीड अच्छा है; यह मूल रूप से अंतर्निहित सॉर्टिंग एल्गोरिथ्म है, प्लस अंत में दो रैखिक गुजरता है, और सूचक इंडिरेक्शन ओवरहेड की एक अतिरिक्त परत है।

इस दृष्टिकोण पर प्रतिक्रिया प्राप्त करने के लिए खुश यहां यह मेरा पूर्ण कार्यान्वयन है:

 /** * - `array`: array to be sorted * - `comparator`: closure that expects indices `i` and `j`, and then * compares `array[i]` to `array[j]` in some way. To force stability, * end with `i - j` as the last "comparison". * * Example: * ``` * let array = [{n: 1, s: "b"}, {n: 1, s: "a"}, {n:0, s: "a"}]; * const comparator = (i, j) => { * const ni = array[i].n, nj = array[j].n; * return ni < nj ? -1 : * ni > nj ? 1 : * i - j; * }; * stableSortInPlace(array, comparator); * // ==> [{n:0, s: "a"}, {n:1, s: "b"}, {n:1, s: "a"}] * ``` */ function stableSortInPlace(array, comparator) { return sortFromIndices(array, findIndices(array, comparator)); } function stableSortedCopy(array, comparator){ let indices = findIndices(array, comparator); let sortedArray = []; for (let i = 0; i < array.length; i++){ sortedArray.push(array[indices[i]]); } return sortedArray; } function findIndices(array, comparator){ // Assumes we don't have to worry about sorting more than // 4 billion elements; if you know the upper bounds of your // input you could replace it with a smaller typed array let indices = new Uint32Array(array.length); for (let i = 0; i < indices.length; i++) { indices[i] = i; } // after sorting, `indices[i]` gives the index from where // `array[i]` should take the value from, so to sort // move the value at at `array[indices[i]]` to `array[i]` return indices.sort(comparator); } // If I'm not mistaken this is O(2n) - each value is moved // only once (not counting the vacancy temporaries), and // we also walk through the whole array once more to check // for each cycle. function sortFromIndices(array, indices) { // there might be multiple cycles, so we must // walk through the whole array to check. for (let k = 0; k < array.length; k++) { // advance until we find a value in // the "wrong" position if (k !== indices[k]) { // create vacancy to use "half-swaps" trick, // props to Andrei Alexandrescu let v0 = array[k]; let i = k; let j = indices[k]; while (j !== k) { // half-swap next value array[i] = array[j]; // array[i] now contains the value it should have, // so we update indices[i] to reflect this indices[i] = i; // go to next index i = j; j = indices[j]; } // put original array[k] back in // and update indices array[i] = v0; indices[i] = i; } } return array; } 

क्या सृजित फ़ंक्शन में निर्मित होगा? http://www.w3schools.com/jsref/jsref_sort.asp