ক্রম সংখ্যায় বাছাই করা ক্রমে তবে শুরুতে `0` এর সাথে


36

জাভাস্ক্রিপ্টে আমার একটি চ্যালেঞ্জ রয়েছে যা আমি ইতিমধ্যে কিছু সময়ের জন্য বের করার চেষ্টা করছি।

এই অ্যারে বিবেচনা করুন:

let arr = [0, 1, 0, 2, 0, 3, 0, 4, 0, 5];

আমি এই ফলাফল আউটপুট দিতে হবে:

arr = [0, 0, 0, 0, 0, 5, 4, 3, 2, 1]

আমি সূত্রের মানটি সামঞ্জস্য করে সামনে শূন্যগুলি অবস্থানের জন্য এই যুক্তিটির লাইনটি অনুসরণ করছি:

arr.sort((x, y) => {
    if (x !== 0) {
        return 1;
    }

    if (x === 0) {
        return -1;
    }

    return y - x;
});

তবে আমি এই ফলাফলটিতে আটকে আছি:

arr = [0, 0, 0, 0, 0, 1, 2, 3, 4, 5]

এটি সমাধান করার জন্য কারও কাছে কি কোনও টিপস রয়েছে?


6
এটির নিশ্চয়তা আছে যে কোনও নেতিবাচক সংখ্যা নেই?
মাইকেল - ক্লে শিরকি

2
শেষ লাইনটি স্যুইচ করা থাকলে এটি ঠিক হয় না return x - y;?
মাকিং হাঁস

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

2
এটি কি কখনও পাওয়া যায় return y - x;? এমনকি জাভাস্ক্রিপ্টেও আমি এমন কোনও কিছুই ভাবতে পারি না যা হবে ===0না !==0
জর্জ টি

2
উত্তরের জন্য জেএসপিআফ: জেএসপিআফ
সালমান এ

উত্তর:


35

আপনি এর ব-দ্বীপ এটি অনুসারে বাছাইয়ের পারে bএবং a(বাছাই সাজানো জন্য) এবং নিতে Number.MAX_VALUEশূন্য মত, falsy মানের জন্য।

এই:

Number.MAX_VALUE - Number.MAX_VALUE

শূন্য সমান।

let array = [0, 1, 0, 2, 0, 3, 0, 4, 0, 5];

array.sort((a, b) => (b || Number.MAX_VALUE) - (a || Number.MAX_VALUE));

console.log(...array);


13
NaNউভয় aএবং bশূন্য হলে আপনার তুলনা ফাংশনটি ফিরে আসবে । এটি অনাকাঙ্ক্ষিত আচরণ হতে পারে।
dan04

20
Array.prototype.sortতুলনামূলক কখনও ফিরে আসলে ফলাফলগুলি বাস্তবায়িত-সংজ্ঞায়িত হয় NaN, সুতরাং এই তুলনাকারী একটি খারাপ ধারণা। এটি চালাক হওয়ার চেষ্টা করে এবং ভুল হয়ে যায়।
ব্যবহারকারী 2357112 মনিকা

3
অ্যারের ভিতরে কোনও উপাদান যদি অনন্ত হয়? তুলনা ফাংশনটি 0 ফেরত দেয় যখন একটি ইনফিনিটি সংখ্যাটি 0 এর সাথে তুলনা করে
মার্কো

4
সবাইকে ধন্যবাদ. আমি সর্বাধিক নম্বর গ্রহণ করি যা নিজে নিজেই বাদ পড়তে পারে এবং আশা করি এই সংখ্যাটি অপের অ্যারেটিতে ব্যবহৃত হয়নি।
নিনা শোল্জ

4
একেবারে অপঠনযোগ্য। দুর্দান্ত, তবে অপঠনযোগ্য।
সালমান একটি

24

যেমন এমডিএন ডকস বলেছেন:

যদি ক এবং খ দুটি উপাদান তুলনা করা হয়, তবে:

যদি এর compareFunction(a, b)চেয়ে কম প্রত্যাবর্তন হয় তবে এর চেয়ে কম সূচককে 0সাজান (অর্থাত্ প্রথমটি আসে)।ab

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

যদি compareFunction(a, b) 0 এর চেয়ে বড় হয়, bতবে একটি (যেমন bপ্রথম আসে) এর চেয়ে কম সূচককে সাজান ।

compareFunction(a, b)যখন উপাদানগুলির একটি নির্দিষ্ট জুড়ি দেওয়া হয় aএবং bএর দুটি যুক্তি হিসাবে সর্বদা একই মান ফেরত পাঠাতে হবে। যদি অসঙ্গতিপূর্ণ ফলাফলগুলি ফিরে আসে, তবে সাজানোর ক্রমটি সংজ্ঞায়িত।

সুতরাং, তুলনা ফাংশন নিম্নলিখিত ফর্ম রয়েছে:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -1;
  }
  if (a is greater than b by the ordering criterion) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

let arr = [0, 1, 0, 2, 0, 3, 0, 4, 0, 5];

arr.sort((x, y) => {
    if (x > 0 && y > 0) {
        return y - x;
    }
    return x - y;
});

console.log(arr);


3
1 ণাত্মক সংখ্যাসহ সমস্ত ইনপুটগুলির জন্য সত্যই সামঞ্জস্যপূর্ণ ( মান হিসাবে সংজ্ঞায়িত ) তুলনা ফাংশনটি দিয়ে এখন পর্যন্ত কেবলমাত্র একমাত্র সমাধান বলে মনে হচ্ছে তা দেওয়ার জন্য +1 ।
ইলমারি করোনেন

3
@ ইলমারি কারোনেন: দুর্ভাগ্যক্রমে, তুলনাটি নেতিবাচক সংখ্যার জন্য সামঞ্জস্যপূর্ণ , তবে এটি নেতিবাচক সংখ্যার জন্য ভুল তুলনা । নেগেটিভগুলি এই তুলনাকারীর সাথে 0 এর আগে বাছাই করে এবং তারা আরোহী ক্রমে সাজান sort
ব্যবহারকারী 2357112 মনিকা

2
@ ব্যবহারকারী 2357112 সাপোর্টমোনিকা তবুও, ওপি নেতিবাচক সংখ্যার জন্য কাঙ্ক্ষিত আচরণ নির্দিষ্ট করে নি এবং এই প্রোটোটাইপের সাহায্যে নেপালি সংখ্যার আচরণকে সামঞ্জস্য করা অপ্রয়োজনীয় যেটি ওপি-র প্রয়োজনীয়তা মাপসই করে। এই উত্তরটি সম্পর্কে ভাল কি তা হ'ল এটি মূর্খতাযুক্ত এবং কাজটি করার জন্য একটি স্ট্যান্ডার্ড তুলনা ফাংশন ব্যবহার করে।
জে ...

13

আপনি যদি দক্ষতার বিষয়ে চিন্তা করেন তবে প্রথমে শূন্যগুলি ফিল্টার করা খুব দ্রুতsortএমনকি আপনি তাদের দিকে তাকিয়েও সময় নষ্ট করতে চান না , সেই বিশেষ কেসটি পরিচালনা করতে আপনার তুলনা কলব্যাকটিতে অতিরিক্ত কাজ যুক্ত করতে দিন।

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

আপনি করতে পারেন দক্ষতার শূন্য সঠিক সংখ্যার পূর্বে লিখুন পরে আপনি সম্পন্ন করেছেন।

ফলাফল কোডটি পড়া খুব সহজ easy আমি টাইপড্রাই ব্যবহার করেছি কারণ এটি দক্ষ এবং সংখ্যার বাছাই সহজ করে । তবে আপনি নিয়মিত অ্যারে দিয়ে এই কৌশলটি ব্যবহার করতে পারেন, এর (a,b)=>a-bজন্য মানক প্রতিমাটি ব্যবহার করে .sort

let arr = [0, 1, 0, 2, 0, 3, 0, 4, 0, 5];

let nonzero_arr = Int32Array.from(arr.filter(n => n != 0));
let zcount = arr.length - nonzero_arr.length;
nonzero_arr.sort();      // numeric TypedArray sorts numerically, not alphabetically

// Reverse the sorted part before copying into the final array.
nonzero_arr.reverse();

 // efficient-ish TypedArray for main result
let revsorted = new Int32Array(arr.length);   // zero-filled full size
revsorted.set(nonzero_arr, zcount);           // copy after the right number of zeros

console.log(Array.from(revsorted));      // prints strangely for TypedArray, with invented "0", "1" keys

/*
   // regular Array result
let sorted = [...Array(zcount).fill(0), ...nonzero_arr]  // IDK if this is efficient
console.log(sorted);
*/

আমি জানি না টাইপড্রেরি .sort()এবং তারপরে .reverseক্রমবর্ধমান ক্রমে সাজানোর জন্য কাস্টম তুলনা ফাংশনটি ব্যবহার করার চেয়ে দ্রুত। অথবা যদি আমরা একটি পুনরুক্তিকারক দিয়ে ফ্লাইতে অনুলিপি করতে পারি এবং করতে পারি।


এগুলি বিবেচনা করার মতো: কেবলমাত্র পূর্ণ দৈর্ঘ্যের একটি টাইপড্রাই ব্যবহার করুন

ব্যবহারের পরিবর্তে, .filterএটির উপর লুপ করুন এবং আপনি যেতে যেতে অ্যারের সামনের দিকে শূন্যগুলি অদলবদল করুন। এটি আপনার ডেটা ধরে এক পাস নেয়।

তারপরে .subarray()একই অন্তর্নিহিত অ্যারেবুফারের অ-শূন্য উপাদানগুলির জন্য একটি নতুন টাইপড্রাই ভিউ পেতে ব্যবহার করুন । বাছাই করা যা আপনাকে শূন্য শুরুর আগে এবং একটি বাছাই করা পুচ্ছ সহ পুরো অ্যারে ছেড়ে দেবে, বাছাইয়ের সাথে কেবল অ-শূন্য উপাদানগুলির দিকে তাকানো থাকবে।

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

টাইপড্ররে রূপান্তর করার .filter() আগে আমি নিয়মিত-অ্যারে ব্যবহার করি। যদি আপনার ইনপুটটি ইতিমধ্যে টাইপড্রে হয় তবে আপনার এই সমস্যা নেই এবং এই কৌশলটি আরও আকর্ষণীয় হয়ে উঠেছে।


এটি সম্ভবত সহজ, এবং / বা আরও বুদ্ধিমান, বা কমপক্ষে আরও কমপ্যাক্ট হতে পারে। আইডিকে যদি জেএস ইঞ্জিনগুলি অনেকগুলি অনুলিপি বা শূন্য-আরম্ভের অপসারণ / অনুকূলিতকরণ পরিচালনা করে, বা যদি এটি টাইপড্রাই পদ্ধতিগুলির পরিবর্তে লুপগুলি ব্যবহার করতে সহায়তা করে যেমন বিপরীত + .set পরিবর্তে পিছনের দিকে অনুলিপি করে। আমি এটির গতি-পরীক্ষা করতে পারিনি; যদি কেউ এটি করতে চায় তবে আমি আগ্রহী।
পিটার

@ সালমানের পরীক্ষার মতে এই উত্তরটি ক্ষুদ্রতর অ্যারেগুলির জন্য ছদ্মবেশের মতো কাজ করে (~ 1000 উপাদানের, যার 10% 0 হয়)। সম্ভবত নতুন অ্যারে তৈরির সমস্ত ব্যথা ব্যথা হয়। অথবা হয়ত টাইপড্রেরির অযত্ন মিশ্রণ এবং নিয়মিত? আমার উত্তরের ২ য় বিভাগে প্রস্তাবিত, টাইপড্রয়ের ভিতরে অল-শূন্য এবং নন-শূন্য + সুবারে সাজানোর ক্ষেত্রে পার্টিশনটি আরও ভাল হতে পারে।
পিটার কর্ডেস

8

আপনার তুলনা ফাংশনটির শর্তটি কেবল এর মতো পরিবর্তন করুন -

let arr = [-1, 0, 1, 0, 2, -2, 0, 3, -3, 0, 4, -4, 0, 5, -5];
arr.sort((a, b) => {
   if(a && b) return b-a;
   if(!a && !b) return 0;
   return !a ? -1 : 1;
});

console.log(arr);


6
যদি কোনও ইনপুট নেতিবাচক হতে পারে তবে এটি একটি সামঞ্জস্যপূর্ণ তুলনাকারী নয়; আপনার তুলনাকারী অনুসারে, 1 এর আগে 0 প্রকার যা 1-এর পূর্বে বাছাই করে 0
সাজায়

নেতিবাচক ইনপুটগুলি সহ আপডেট হয়েছে
হারুনুর রশিদ

@ সালমানা, উভয়ই যদি শূন্য হয় তবে শর্তটি !aএখনও সত্য। এটি ফিরে আসবে-1
হারুনুর রশিদ

আমি মনে করি না যে এটি একটি বড় চুক্তি এবং খ উভয়ই শূন্য @ সালমানা
হারুনুর রশিদ

1
ঠিক বলতে গেলে, আমি উত্তরটি সম্পাদনা করেছি। a=b=0
হারুনুর রশিদ

6

এখানে কোড গল্ফ খেলছে না:

let arr = [0, 1, 0, 2, 0, 3, 0, 4, 0, 5, -1];
arr.sort(function(a, b) {
  if (a === 0 && b !== 0) {
    // a is zero b is nonzero, a goes first
    return -1;
  } else if (a !== 0 && b === 0) {
    // a is nonzero b is zero, b goes first
    return 1;
  } else {
    // both are zero or both are nonzero, sort descending
    return b - a;
  }
});
console.log(arr.toString());


5

যদি ইতিমধ্যে বিদ্যমান থাকে তবে আপনার নিজস্ব সংখ্যা বাছাই লিখবেন না। আপনি যা করতে চান তা হ'ল শিরোনামে যা বলেছেন; শুরুর দিকে শূন্য ছাড়া অবতরণ ক্রমে সংখ্যা সাজান।

const zeroSort = arr => [...arr.filter(n => n == 0),
                         ...new Float64Array(arr.filter(n => n != 0)).sort().reverse()];

console.log(zeroSort([0, 1, 0, 2, 0, 3, 0, 4, 0, 500]));

আপনার প্রয়োজন নেই এমন কোনও কোড লিখবেন না; আপনি এটি ভুল পেতে পারে।

আপনি অ্যারেটি কী ধরণের নম্বর পরিচালনা করতে চান তার উপর ভিত্তি করে টাইপডরে বাছাই করুন । ফ্লোট 64 একটি ভাল ডিফল্ট কারণ এটি সমস্ত সাধারণ জেএস নম্বর পরিচালনা করে।


@ ইলমারি কারোনেন আরও ভাল?
জলি জোকার

আপনার দু'বার ফিল্টার করার দরকার নেই; আমার উত্তর হিসাবে দেখা যায় আপনি একবার ফিল্টার করতে পারেন এবং একটি সংখ্যা পেতে দৈর্ঘ্য বিয়োগ করতে পারেন Array(n).fill(0)
পিটার কর্ডেস

@ পিটারকর্ডস যদিও এটি সম্ভবত সহজ বলা যেতে পারে, আমি মনে করি কোডটি পড়তে কম সহজ হওয়ার জন্য এত দীর্ঘ হয়ে যায়
JollyJoker

হ্যাঁ, দক্ষতার জন্য একটি টিএমপি ভারের জন্য 1 অতিরিক্ত লাইন লাগবে। আমার উত্তরটি একাধিক অতিরিক্ত লাইন ব্যবহার করে কারণ আমি সি এবং সি ++ এবং সমাবেশ ভাষা ব্যবহার করেছি এবং আরও পৃথক রেখাগুলি থাকায় কমপ্লায়ার-উত্পন্ন asm এটির জন্য দায়ী বিবৃতিতে ফিরে যখন অনুকূলিত / প্রোফাইলিং করা যায় তখন এটি চিহ্নিত করা সহজ করে তোলে। প্লাস আমি জেএস সাধারণত করি না তাই এগুলি কয়েকটি লাইনে ক্র্যাম করার কোনও প্রয়োজন অনুভব করি না। কিন্তু আপনি কাজ করতে পারে let f64arr = new Float64Array(arr.filter(n => n != 0))তাহলে [ ...Array(arr.length - f64arr.length).fill(0),... তাই এটি 1 অতিরিক্ত লাইন যোগ করা হয়েছে এবং শেষ লাইনটি সহজসাধ্য।
পিটার

4

আপনি এটি এইভাবে করতে পারেন:

let arr = [0, 1, 0, 2, 0, 3, 0, 4, 0, 5];

let result = arr.sort((a,b) => {
  if(a == 0 || b == 0)
    return a-b;
  return b-a;
})
console.log(result)

অথবা আপনি এটি করতে পারেন:

let arr = [0, 1, 0, 2, 0, 3, 0, 4, 0, 5];

let result = arr.sort().sort((a,b) => {
  if(a > 0 && b > 0)
    return b-a
  return 0
})

console.log(result)


4
আপনার প্রথম সমাধানটিতে হারুনুর রশিদের উত্তর হিসাবে নেতিবাচক ইনপুটগুলির সাথে একই ধারাবাহিকতা সমস্যা রয়েছে। দ্বিতীয় হয় সামঞ্জস্যপূর্ণ কিন্তু শূন্য সমান তাদের পারস্পরিক সাজানোর ক্রম রেখে একইরূপে সব ঋণাত্মক সংখ্যা undefined।
ইলমারি করোনেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.