কোন অংশে একটি নম্বর ক্যাপচার সবচেয়ে মার্জিত উপায় কি?


127

চল বলি x , aএবং bসংখ্যা হয়। xসেগমেন্টের সীমানায় আমার ক্যাপ করা দরকার [a, b]

আমি লিখতে পারি Math.max(a, Math.min(x, b)) , তবে আমি এটি পড়তে খুব সহজ মনে করি না। এটিকে আরও পঠনযোগ্য উপায়ে লেখার জন্য কারও কি চতুর উপায় আছে?

উত্তর:


197

আপনি যেভাবে এটি করেন তা বেশ মান। আপনি একটি ইউটিলিটি clampফাংশন সংজ্ঞায়িত করতে পারেন :

/**
 * Returns a number whose value is limited to the given range.
 *
 * Example: limit the output of this computation to between 0 and 255
 * (x * 255).clamp(0, 255)
 *
 * @param {Number} min The lower boundary of the output range
 * @param {Number} max The upper boundary of the output range
 * @returns A number in the range [min, max]
 * @type Number
 */
Number.prototype.clamp = function(min, max) {
  return Math.min(Math.max(this, min), max);
};

(যদিও অন্তর্নির্মিত ভাষার প্রসারকে সাধারণত অস্বীকার করা হয়)


ওপস আপনি আমার টাইপগুলি অনুলিপি / আটকানো (সর্বাধিক এবং সর্বনিম্ন)
স্যামুয়েল রসিল

5
নাহ, আমি এটি সাইট থেকে পেয়েছি। এর নেস্টিং / এক্সিকিউশন অর্ডারMath.min এবং Math.maxদীর্ঘ এর প্যারামিটার হিসাবে হিসাবে অপ্রাসঙ্গিক Math.minহয় maxএবং প্যারামিটার Math.maxহয় min
ওটো অলমিনেঞ্জার

23
নেটিভ প্রোটোটাইপগুলি প্রসারিত করা ( Number.prototypeএই ক্ষেত্রে) বিভিন্ন কারণে অসুস্থ পরামর্শ দেওয়া হয়। "খারাপ অনুশীলন: ডেভেলপার প্রোটোটাইপগুলির সম্প্রসারণ" বিকাশকারী.মোজিলা.আর.ইন- ইউএস / ডকস / ওয়েবে / জাভা স্ক্রিপ্ট / এ দেখুন
ইউএস

68

কম "গণিত" ভিত্তিক দৃষ্টিভঙ্গি, তবে এটিও কাজ করা উচিত, এইভাবে </> পরীক্ষা উন্মুক্ত করা হয়েছে (মিনিমেক্সিংয়ের চেয়ে আরও বেশি বোধগম্য) তবে এটি "পাঠযোগ্য" দ্বারা আপনি কী বোঝাতে চেয়েছেন তা নির্ভর করে

function clamp(num, min, max) {
  return num <= min ? min : num >= max ? max : num;
}

4
এই আইডিয়োমে <এবং> কে <= এবং> = এর সাথে প্রতিস্থাপন করা আরও ভাল, যাতে সম্ভবত আরও একটি তুলনা সম্পন্ন হয়। সেই সংশোধনীর সাথে, এটি অবশ্যই আমার পছন্দসই উত্তর: সর্বাধিক মিনিট বিভ্রান্তিকর এবং ত্রুটির প্রবণ।
ডন হ্যাচ

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

5
এটি দ্রুত নয়। ম্যাথ.মিন / সর্বোচ্চ সমাধানটি দ্রুততম jsperf.com/math-clamp/9
ম্যানুয়েল ডি

1
@ মানুয়েলডিআইওরিও হাহ? ক্রোমের বর্তমান সংস্করণের অধীনে, সরল ত্রৈমাসিকটি ম্যাথ.মিন / সর্বোচ্চের চেয়ে দ্বিগুণ দ্রুত - এবং আপনি যদি আরও বেশি ব্যয়বহুল Math.random()কল থেকে ওভারহেডটি সরিয়ে থাকেন তবে এই সাধারণ পদ্ধতিরটি 10 এক্স দ্রুত
mindplay.dk


48

ECMAScript 2017 এর জন্য আপডেট:

Math.clamp(x, lower, upper)

তবে মনে রাখবেন যে আজকের হিসাবে এটি একটি স্টেজ 1 প্রস্তাব । যতক্ষণ না এটি ব্যাপকভাবে সমর্থিত হয়, আপনি পলিফিল ব্যবহার করতে পারেন ।


4
আপনি যদি এই প্রস্তাব এবং অন্যদের ট্র্যাক করতে চান তবে দেখুন: github.com/tc39/proposals
gfullam

5
Tc39 / प्रस्ताव রেপোতে আমি এই প্রস্তাবটি খুঁজে পাইনি
কলিন ডি

যারা খুঁজছেন তাদের জন্য প্রস্তাবটি মঞ্চ 1 প্রস্তাবের অধীনে "ম্যাথ এক্সটেনশানস" হিসাবে তালিকাভুক্ত করা হয়েছে । আসল প্রস্তাবটি এখানে: github.com/rwaldron/proposal-math- এক্সটেনশনগুলি
উইকিনিলিয়ামস

14
Math.clip = function(number, min, max) {
  return Math.max(min, Math.min(number, max));
}

2
এই সমাধানটি আসলে বেশ দ্রুততর, যদিও আমি prototypeযখন ফাংশনটি ব্যবহার করতে চাই তখন আমি খুব মার্জিতটিকে প্রসারিত করার বিষয়টি বিবেচনা করি ।
ম্যাক্সআর্ট

11

এটি "সবেমাত্র ব্যবহারের জন্য একটি লাইব্রেরি" উত্তর হতে চাইছে না তবে আপনি যদি লোড্যাশ ব্যবহার করছেন তবে আপনি এটি ব্যবহার করতে পারেন .clamp:

_.clamp(yourInput, lowerBound, upperBound);

যাতে:

_.clamp(22, -10, 10); // => 10

লোডাশ উত্স থেকে নেওয়া এর বাস্তবায়ন এখানে দেওয়া হল :

/**
 * The base implementation of `_.clamp` which doesn't coerce arguments.
 *
 * @private
 * @param {number} number The number to clamp.
 * @param {number} [lower] The lower bound.
 * @param {number} upper The upper bound.
 * @returns {number} Returns the clamped number.
 */
function baseClamp(number, lower, upper) {
  if (number === number) {
    if (upper !== undefined) {
      number = number <= upper ? number : upper;
    }
    if (lower !== undefined) {
      number = number >= lower ? number : lower;
    }
  }
  return number;
}

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

npm i --save lodash.clamp

6

আপনি যদি এস arrow টি তীর ফাংশন ব্যবহার করতে সক্ষম হন তবে আপনি আংশিক অ্যাপ্লিকেশন পদ্ধতিরও ব্যবহার করতে পারেন:

const clamp = (min, max) => (value) =>
    value < min ? min : value > max ? max : value;

clamp(2, 9)(8); // 8
clamp(2, 9)(1); // 2
clamp(2, 9)(10); // 9

or

const clamp2to9 = clamp(2, 9);
clamp2to9(8); // 8
clamp2to9(1); // 2
clamp2to9(10); // 9

আপনি যখন কোনও সংখ্যার বাতাটি দেখতে চান প্রতিটি সময় কোনও ক্রিয়াকলাপ তৈরি করা খুব অকার্যকর বলে মনে হয়
জর্জ

1
সম্ভবত আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে। এটি একটি সেট পরিসীমা সহ ক্ল্যাম্প তৈরির জন্য কেবল একটি কারখানার কাজ। আপনি একবারে তৈরি করতে পারেন এবং আপনার অ্যাপ্লিকেশন জুড়ে যা পুনরায় ব্যবহার করতে পারেন। একাধিকবার কল করতে হবে না। আপনার ব্যবহারের ক্ষেত্রে যে কোনও সেট ব্যাপ্তিতে লক করার দরকার নেই সেগুলি ব্যবহারের জন্য সরঞ্জামও নাও হতে পারে।
18

@ জর্জি আপনার যদি এই সীমাটি বজায় রাখার দরকার না হয় তবে কেবল অভ্যন্তরীণ তীর ফাংশনটি সরিয়ে ফেলুন এবং মানের প্যারামিটারটি বাইরের তীর ফাংশনে সরিয়ে দিন
অ্যালিসন নুনস

6

আপনি যদি কোনও ফাংশন সংজ্ঞায়িত করতে না চান তবে এটির মতো লেখালেখি করা Math.min(Math.max(x, a), b)খারাপ নয়।


0

তীর যৌনতার চেতনায় আপনি একটি মাইক্রো বাতা / সীমাবদ্ধতা / গেট / & সি তৈরি করতে পারেন। বিশ্রাম পরামিতি ব্যবহার করে ফাংশন

var clamp = (...v) => v.sort((a,b) => a-b)[1];

তারপরে তিনটি মান পাস করুন

clamp(100,-3,someVar);

এটি আবার, যদি সেক্সি দ্বারা, আপনার অর্থ 'শর্ট'


আপনার অ্যারে এবং বাছাইয়ের জন্য ব্যবহার করা উচিত নয় clamp, আপনার জটিল যুক্তি (এমনকি এটি "সেক্সি" হলেও) পারফ একটি মারাত্মক আঘাত হানবে
অ্যান্ড্রু ম্যাকোলাশ

0

এটি যদি / অন্যটি যা মাইন করা হয় ত্রৈমাসিক বিকল্পের সমতুল্য হয় তবে পঠনযোগ্যতার ত্যাগ না করে তবে এটি তিনটি বিকল্পকে প্রসারিত করে।

const clamp = (value, min, max) => {
  if (value < min) return min;
  if (value > max) return max;
  return value;
}

Minifies 35b (বা 43 বি ব্যবহার করে function):

const clamp=(c,a,l)=>c<a?a:c>l?l:c;

এছাড়াও, আপনি কি পারফ টুলিং বা ব্রাউজার ব্যবহার করেন তার উপর নির্ভর করে আপনি গণিত ভিত্তিক প্রয়োগ বা ত্রৈমাসিক ভিত্তিক প্রয়োগ দ্রুততর কিনা তা বিভিন্ন ফলাফল পান। মোটামুটি একই পারফরম্যান্সের ক্ষেত্রে, আমি পঠনযোগ্যতা বেছে নেব।


-5

আমার পছন্দ:

[min,x,max].sort()[1]

12
ডাউনভোটিং কারণ এটি কাজ করে না। [1,5,19].sort()[1]19 এ ফিরে আসে It এটি ঠিক করা যেতে পারে: [min,x,max].sort(function(a, b) { return a - b; })[1]তবে এটি আর সেক্সি নয়। পাশাপাশি যখন ভারী ব্যবহার করা হয় তখন কেবল তিনটি সংখ্যার তুলনা করার জন্য একটি নতুন অ্যারে তৈরি করা একটি পারফরম্যান্সের সমস্যা হতে পারে।
কায়াহর

5
যাইহোক এই +1 দেওয়া, কারণ সেক্সি গণনা করা হয়।
ডন হ্যাচ

3
আইএমএইচও এটি অন্য যে কোনও বিকল্পের চেয়ে বিশেষত তীর ফাংশনগুলির চেয়ে বেশি পঠনযোগ্য:[min, x, max].sort((a,b) => a-b)[1]
জাইউস

4
কেন এটি সর্বদা কাজ করে না তার কারণ হ'ল বাছাই পদ্ধতিটি সংখ্যার মানগুলি সঠিকভাবে তুলনা করে না। (এটি তাদের সাথে স্ট্রিংয়ের মতো আচরণ করে)
জন লিউনহেগেন

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