জাভাস্ক্রিপ্টে দ্রুত স্থিতিশীল অ্যালগরিদম বাস্তবায়ন implementation


103

আমি প্রায় 200-300 অবজেক্টের একটি অ্যারে বাছাই করতে দেখছি, একটি নির্দিষ্ট কী এবং প্রদত্ত আদেশে (asc / desc) বাছাই করে। ফলাফলের ক্রমটি অবশ্যই সামঞ্জস্যপূর্ণ এবং স্থিতিশীল হতে হবে।

ব্যবহারের জন্য সেরা অ্যালগরিদম কী হবে এবং আপনি জাভাস্ক্রিপ্টে এর প্রয়োগের একটি উদাহরণ দিতে পারেন?

ধন্যবাদ!


5
যেহেতু কমপক্ষে Chrome এর অ্যারে বাছাই করা স্থিতিশীল বলে মনে হচ্ছে না, তাই বিল্ট-ইন অ্যারে বাছাইয়ের উপর নির্ভর করা আপনার পক্ষে বিকল্প নয়।
নসরেডনা

সংক্ষিপ্তসার হিসাবে: আমি অ্যারে.সর্ট স্থায়িত্বের অসঙ্গতিগুলির কারণে হ্যান্ড রোলড মার্জ সাজ্টের সাথে গিয়েছিলাম mainly সাহায্যের জন্য সবাইকে ধন্যবাদ!
উইলিয়াম ক্যাসারিন

"স্থিতিশীল" বাছাই বলতে আমরা কী বুঝি?
mowwwalker

2
@ মাওওয়ালকার স্থিতিশীল বাছাই এমন একটি সাজান যা একই সংগ্রহের মান সহ সমস্ত আইটেমগুলি মূল সংগ্রহের মতো একই ক্রমে রেখে দেওয়া হয়। en.wikedia.org/wiki/Sorting_algorithm#Stability
Kornelije Petak

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

উত্তর:


113

অ-স্থিতিশীল সাজানোর ক্রিয়া থেকে স্থিতিশীল বাছাই করা সম্ভব।

বাছাইয়ের আগে আপনি সমস্ত উপাদানগুলির অবস্থান পান। আপনার সাজানোর অবস্থায় যদি উভয় উপাদান সমান হয় তবে আপনি অবস্থান অনুসারে বাছাই করুন।

Tada! আপনি একটি স্থিতিশীল বাছাই পেয়েছি।

আপনি যদি এই কৌশল এবং কীভাবে এটি বাস্তবায়ন করতে চান সে সম্পর্কে আরও জানতে চান তবে আমি আমার ব্লগে এটি সম্পর্কে একটি নিবন্ধ লিখেছি: http://blog.vjeux.com/2010/javascript/javascript-sorting-table.html


32
আপনি দয়া করে পোস্ট করতে এবং আপনার ব্লগে লিঙ্ক করার পরিবর্তে এখানে উত্তর সরবরাহ করতে পারেন! ধন্যবাদ
মোহাম্মদ করমানি

4
একটি সমাধানের একটি লিঙ্ক স্বাগত, তবে দয়া করে আপনার উত্তরটি কার্যকর না হওয়া নিশ্চিত করুন: লিঙ্কটির চারপাশে প্রসঙ্গটি যুক্ত করুন যাতে আপনার সহ ব্যবহারকারীদের কিছু ধারণা থাকতে পারে এটি কী এবং কেন এটি রয়েছে, তবে আপনি পৃষ্ঠার সর্বাধিক প্রাসঙ্গিক অংশটি উদ্ধৃত করুন লক্ষ্য পৃষ্ঠাটি অনুপলব্ধ ক্ষেত্রে লিঙ্কটি পুনরায় সংযুক্ত করুন। লিঙ্কের চেয়ে সামান্য বেশি উত্তর মুছতে পারে।
স্যামুয়েল লিউ

@ ভাইজেক্স যেহেতু এটি একটি জনপ্রিয় হতে চলেছে, আপনি কি এই উত্তরটিতে প্রাসঙ্গিক কোডটি আটকে দেবেন? এটা অনেক সাহায্য করবে! ধন্যবাদ!
উইলিয়াম ক্যাসারিন

34

যেহেতু আপনি স্থিতিশীল কোনও কিছুর সন্ধান করছেন, একত্রিত করার পদ্ধতিটি করা উচিত।

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

সম্পাদনা করুন:

এই পোস্ট অনুসারে , এটি দেখে মনে হচ্ছে অ্যারে some কিছু বাস্তবায়নে বাছাই করা একত্রিত বাছাই করে।


++ মার্জ বাছাই আমার প্রিয়। এটি কোনও সহজ খারাপ পরিস্থিতি সহ সহজ এবং স্থিতিশীল।
মাইক ডুনলাভে

ওয়েবসাইটের লিঙ্কটি নিচে রয়েছে :(
ahitt6345

উদাহরণস্বরূপ একটি নতুন ওয়েবসাইট খুঁজে পেল।
kemiller2002

7
দ্রষ্টব্য: Array#shiftও (এন) সময়ে কাজ করতে পারে এবং সুতরাং mergeও (এন * এন) এ।
4esn0k

22

ES2017 বৈশিষ্ট্যগুলি যেমন তীর ফাংশন এবং ডেস্ট্রাকচারিং ব্যবহার করে একই জিনিসটির কিছুটা সংক্ষিপ্ত সংস্করণ:

ক্রিয়া

var stableSort = (arr, compare) => arr
  .map((item, index) => ({item, index}))
  .sort((a, b) => compare(a.item, b.item) || a.index - b.index)
  .map(({item}) => item)

এটি ইনপুট অ্যারে গ্রহণ করে এবং ফাংশন তুলনা করে:

stableSort([5,6,3,2,1], (a, b) => a - b)

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

পরীক্ষা

আমরা যদি নিম্নলিখিত inputঅ্যারেটি গ্রহণ করি তবে প্রাথমিকভাবে বাছাই করা weight:

// sorted by weight
var input = [
  { height: 100, weight: 80 },
  { height: 90, weight: 90 },
  { height: 70, weight: 95 },
  { height: 100, weight: 100 },
  { height: 80, weight: 110 },
  { height: 110, weight: 115 },
  { height: 100, weight: 120 },
  { height: 70, weight: 125 },
  { height: 70, weight: 130 },
  { height: 100, weight: 135 },
  { height: 75, weight: 140 },
  { height: 70, weight: 140 }
]

তারপরে এটি heightব্যবহার করে বাছাই করুন stableSort:

stableSort(input, (a, b) => a.height - b.height)

ফলাফল স্বরূপ:

// Items with the same height are still sorted by weight 
// which means they preserved their relative order.
var stable = [
  { height: 70, weight: 95 },
  { height: 70, weight: 125 },
  { height: 70, weight: 130 },
  { height: 70, weight: 140 },
  { height: 75, weight: 140 },
  { height: 80, weight: 110 },
  { height: 90, weight: 90 },
  { height: 100, weight: 80 },
  { height: 100, weight: 100 },
  { height: 100, weight: 120 },
  { height: 100, weight: 135 },
  { height: 110, weight: 115 }
]

তবে inputঅন্তর্নির্মিত Array.sort()(ক্রোম / নোডজেএস এ) ব্যবহার করে একই অ্যারে বাছাই করা :

input.sort((a, b) => a.height - b.height)

রিটার্নস:

var unstable = [
  { height: 70, weight: 140 },
  { height: 70, weight: 95 },
  { height: 70, weight: 125 },
  { height: 70, weight: 130 },
  { height: 75, weight: 140 },
  { height: 80, weight: 110 },
  { height: 90, weight: 90 },
  { height: 100, weight: 100 },
  { height: 100, weight: 80 },
  { height: 100, weight: 135 },
  { height: 100, weight: 120 },
  { height: 110, weight: 115 }
]

সম্পদ

হালনাগাদ

Array.prototype.sort ভি 8 ভি 7.0 / ক্রোম 70 এ এখন স্থিতিশীল!

পূর্বে, ভি 8 10 টিরও বেশি উপাদান সহ অ্যারেগুলির জন্য একটি অস্থির কুইকসোর্ট ব্যবহার করত। এখন, আমরা স্থিতিশীল টিমসোর্ট আলগোরিদিম ব্যবহার করি।

উৎস


1
stableSortফাংশন একটি সত্যিই মহান সমাধান!
lhermann

16

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

এটি আপনাকে সাধারণ 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"];

4
মনে রাখবেন এটি দেশীয় ধরণের সাথে বৈষম্যপূর্ণ, যা স্থানে কাজ করে , যার অর্থ এটি কেবল বাদ দেওয়া যায় না
এরিক

3
সম্ভবত স্থিতিশীল, তবে এই পদ্ধতিটি দেশীয়ের চেয়ে প্রায় 20 গুণ কম ধীরে ধীরেarray.sort এবং স্ট্রিং এবং পূর্ণসংখ্যা উভয়ের জন্য এখানে পরীক্ষা দেখুন -> jsfiddle.net/QC64j
ডেভিডকনরাদ

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

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

2
যে কেউ স্থানে থাকা, ড্রপ-ইন সমাধান চান যা এই প্রয়োগের চেয়ে অনেক দ্রুত, আমার উত্তরটি দেখুন
প্যাট্রিক রবার্টস

10

আপনি এই উত্তরের দৃser়তার উপর ভিত্তি করে দেশীয় বাস্তবায়ন নির্বিশেষে একটি স্থিতিশীল বাছাই বাস্তবায়নের জন্য নিম্নলিখিত পলফিল ব্যবহার করতে পারেন :

// 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) + '%')

উপরে প্রয়োগ করা কর্মক্ষমতা পরীক্ষা stableSort()চালানো sort(), ক্রোম সংস্করণে 59-61 এর গতি প্রায় 57% গতিতে দেখা যায় appears

ব্যবহার .bind(compareFunction)আবৃত বেনামী ফাংশন উপর মধ্যে stableSort()একটি অপ্রয়োজনীয় বিশ্লেষণ করা রেফারেন্স এড়িয়ে 38% থেকে যে আপেক্ষিক কর্মক্ষমতা চালচিত্রকে compareFunctionপ্রসঙ্গে এটা পরিবর্তে বরাদ্দ করে প্রতিটি কলের উপর।

হালনাগাদ

লার্জিকাল শর্ট সার্কিটগুলিতে টার্নারি অপারেটর পরিবর্তিত হয়েছে, যা গড়ের তুলনায় আরও ভাল পারফর্ম করে efficiency (দক্ষতায় 2-3% পার্থক্য দেখা যায়)।


5

নীচের সরবরাহ করা অ্যারে বাছাই করে সরবরাহ করা তুলনা ফাংশন প্রয়োগ করে, তুলনা ফাংশনটি 0 ফেরত আসল সূচক তুলনা ফিরিয়ে আনলে:

function stableSort(arr, compare) {
    var original = arr.slice(0);

    arr.sort(function(a, b){
        var result = compare(a, b);
        return result === 0 ? original.indexOf(a) - original.indexOf(b) : result;
    });

    return arr;
}

নীচের উদাহরণে সমানাধীন নামের ক্রম ধরে রাখার সাথে সাথে একটি নামের অ্যারের নাম সাজানো হয়েছে:

var names = [
	{ surname: "Williams", firstname: "Mary" },
	{ surname: "Doe", firstname: "Mary" }, 
	{ surname: "Johnson", firstname: "Alan" }, 
	{ surname: "Doe", firstname: "John" }, 
	{ surname: "White", firstname: "John" }, 
	{ surname: "Doe", firstname: "Sam" }
]

function stableSort(arr, compare) {
    var original = arr.slice(0);

    arr.sort(function(a, b){
        var result = compare(a, b);
        return result === 0 ? original.indexOf(a) - original.indexOf(b) : result;
    });
	
    return arr;
}

stableSort(names, function(a, b) { 
	return a.surname > b.surname ? 1 : a.surname < b.surname ? -1 : 0;
})

names.forEach(function(name) {
	console.log(name.surname + ', ' + name.firstname);
});


অ্যারেতে আদিম ধরণের বা সদৃশ উপাদানগুলির জন্য স্থিতিশীল নয়। jQuery.expando.split( "" ).sort( ( a, b ) => 0 ).join( "" ) === jQuery.expando
মঙ্গল গ্রহে

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 a.a - b.a;
});
console.log(res);

আর একটি উত্তর এটির জন্য ইঙ্গিত করেছে, কিন্তু তেহ কোডজ পোস্ট করে নি।

তবে, এটি আমার মানদণ্ড অনুসারে দ্রুত নয় । আমি একটি কাস্টম তুলনামূলক ফাংশন গ্রহণ করতে মার্জ সাজ্ট ইমপ্লিকে সংশোধন করেছি এবং এটি আরও দ্রুত ছিল।


আপনার মানদণ্ডটি কি সঠিক? দেখে মনে হচ্ছে, আপনার "স্থিতিশীলতা" ইনপুট অ্যারে, অন্য প্রকারের - পরিবর্তন করে না এবং কর যেমন আপনি "সেটআপ" চলাকালীন "আর" পুনরায় তৈরি করেন নি, অন্য ধরণের সাজান ইতিমধ্যে সাজানো অ্যারেগুলি ....
4esn0k

@ 4esn0k আপনি কি ভুল পড়েছেন? আমি বলেছিলাম যে আমার স্থিতিশীলতার কাজটি দ্রুত ছিল না।
ছাগল

@ গোটা, আহ, আমাকে ক্ষমা করুন
4esn0k

3

আপনি টিমসোর্টও ব্যবহার করতে পারেন। এটি একটি জটিল জটিল অ্যালগরিদম (৪০০+ লাইন, অতএব এখানে কোনও উত্স কোড নেই), তাই উইকিপিডিয়াটির বিবরণ দেখুন বা বিদ্যমান জাভাস্ক্রিপ্ট প্রয়োগগুলির মধ্যে একটি ব্যবহার করুন:

জিপিএল 3 বাস্তবায়ন । অ্যারে.প্রোটোটাইপ.পেমসোর্ট হিসাবে প্যাকেজড। জাভা কোডের একটি পুনর্লিখন বলে মনে হচ্ছে।

পাবলিক ডোমেন বাস্তবায়ন টিউটোরিয়াল হিসাবে, নমুনা কোডটি কেবল পূর্ণসংখ্যার সাথে এর ব্যবহার দেখায়।

টিমসোর্ট হ'ল মার্জসোর্ট এবং শফল সাজ্টের একটি অত্যন্ত অনুকূলিত সংকর এবং পাইথন এবং জাভাতে (1.7+) ডিফল্ট বাছাই করা অ্যালগরিদম। এটি একটি জটিল অ্যালগরিদম, কারণ এটি বিভিন্ন বিশেষ ক্ষেত্রে বিভিন্ন অ্যালগরিদম ব্যবহার করে। তবে ফলস্বরূপ এটি বিভিন্ন পরিস্থিতিতে বিভিন্ন সময়ে অত্যন্ত দ্রুত।


1

Http://www.stoime.com/blog/2010/07/02/friday-algorithms- জাভাস্ক্রিপ্ট- নিমজ্জিত / সর্ট /

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

0

আমাকে একটি স্বেচ্ছাসেবী কলাম দ্বারা বহুমাত্রিক অ্যারে বাছাই করতে হবে এবং তার পরে অন্য দ্বারা। আমি এই ফাংশনটি বাছাই করতে ব্যবহার করি:

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 কখনও শূন্য ফেরায় না, যেখানে "সাজান" ফাংশনের কিছু বাস্তবায়ন এমন সিদ্ধান্ত নেয় যা সঠিক নাও হতে পারে।

এটিও বেশ সুন্দর fast


0

মার্জ সার্ট ব্যবহার করে আপনি কীভাবে জেএস ডিফল্ট অ্যারে অবজেক্টটিকে প্রোটোটাইপ পদ্ধতিতে প্রসারিত করতে পারেন তা এখানে । এই পদ্ধতিটি একটি নির্দিষ্ট কী (প্রথম প্যারামিটার) এবং একটি প্রদত্ত আদেশ ('asc' / 'desc' কে দ্বিতীয় প্যারামিটার হিসাবে) বাছাই করার অনুমতি দেয়

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

উপরের স্নিপেটটি আপনার ব্রাউজার কনসোলে ফেলে দিয়ে আপনি নিজেই এটি পরীক্ষা করে দেখতে পারেন:

var x = [2,76,23,545,67,-9,12];
x.mergeSort(); //[-9, 2, 12, 23, 67, 76, 545]
x.mergeSort(undefined, 'desc'); //[545, 76, 67, 23, 12, 2, -9]

বা বস্তুর অ্যারেতে একটি নির্দিষ্ট ক্ষেত্রের উপর ভিত্তি করে অর্ডার করুন:

var y = [
  {startTime: 100, value: 'cat'},
  {startTime: 5, value: 'dog'},
  {startTime: 23, value: 'fish'},
  {startTime: 288, value: 'pikachu'}
]
y.mergeSort('startTime');
y.mergeSort('startTime', 'desc');

0

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

  • আমি সত্যিই কেবল sort()এপিআই- তে কিছু অনুরূপ থাকতে চাই , যেখানে আমি তুলনামূলক ফাংশনটি পাস করতে পারি।
  • কখনও কখনও আমি জায়গায় স্থানে বাছাই করতে পারি এবং কখনও কখনও আমার ডেটা অপরিবর্তনীয় (কারণ Redux) হয় এবং এর পরিবর্তে আমার একটি বাছাই করা অনুলিপি প্রয়োজন। সুতরাং আমি প্রতিটি ব্যবহারের ক্ষেত্রে একটি স্থিতিশীল বাছাই ফাংশন প্রয়োজন।
  • 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;
}

0

আমি জানি এটির যথেষ্ট উত্তর দেওয়া হয়েছে। আমি স্রেফ একটি পোস্টে এগিয়ে যেতে চেয়েছিলাম যারা এখানে খুঁজছেন যে কেউ তার জন্য দ্রুত টিএস বাস্তবায়ন।

export function stableSort<T>( array: T[], compareFn: ( a: T, b: T ) => number ): T[] {
    const indices = array.map( ( x: T, i: number ) => ( { element: x, index: i } ) );

    return indices.sort( ( a, b ) => {
        const order = compareFn( a.element, b.element );
        return order === 0 ? a.index - b.index : order;
    } ).map( x => x.element );
}

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

উল্লিখিত কয়েকটি সমাধান আরও পরিবেশনামূলক, ভেবেছিল এটি অভ্যন্তরীণ ব্যবহার করে কম কোডও হতে পারে Array.prototype.sort

(একটি জাভাস্ক্রিপ্ট সমাধানের জন্য, কেবল সমস্ত প্রকার সরিয়ে ফেলুন)


0

ভি 8 ডি ব্লগ অনুসারে এবং ক্যানিউজ.কম Array.sort আধুনিক ব্রাউজারগুলিতে অনুমান অনুসারে ইতোমধ্যে স্থিতিশীল, সুতরাং আপনার নিজের সমাধানটি রোল করার দরকার নেই। আমি দেখতে পাচ্ছি একমাত্র ব্যতিক্রম এজ, যা শীঘ্রই ক্রোমিয়ামে চলে যেতে হবে এবং পাশাপাশি এটি সমর্থন করা উচিত।


0

function sort(data){
    var result=[];
    var array = data;
    const array2=data;
    const len=array2.length;
    for(var i=0;i<=len-1;i++){
    var min = Math.min.apply(Math,array)
    result.push(min);
    var index=array.indexOf(min)
    array.splice(index,1);
    }
    return result;
}   
sort([9,8,5,7,9,3,9,243,4,5,6,3,4,2,4,7,4,9,55,66,33,66]);


-1

গণনা বাছাই করা মার্জ সাজ্টের চেয়ে দ্রুত (এটি ও (এন) সময়ে সঞ্চালিত হয়) এবং এটি পূর্ণসংখ্যার ব্যবহারের উদ্দেশ্যে is

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

12
কিছু কথা বলা দরকার: 1. গণনা বাছাই কেবল একটি ঘন সংখ্যা জায়গায় ভাল কাজ করে। (অ্যারে [1, 2e9, 1e9] বাছাই করার চেষ্টা করুন) ২. লুপগুলি যখন লিখুন তেমন লিখবেন না। 3. এলোমেলোভাবে ম্যাথ নেমস্পেসে জিনিস যুক্ত করবেন না। ৪. আপনি সেমিকোলনগুলির সাথে বন্ধু তৈরির বিষয়ে বিবেচনা করতে চাইতে পারেন।
ডোমি

এছাড়াও, অ্যারেতে সদৃশ মান রয়েছে এমন ক্ষেত্রে এটি সর্বদা চলবে। উদাহরণস্বরূপ, array [3, 1, 3]hashes to [undefined, 1, undefined, 3]। আমরা দুটি অপরিবর্তিত মান পাই, তবে অ্যালগোরিদম তাদের মধ্যে তিনটি হওয়ার আশা করে।
এমকেপিএস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.