यदि कोई संख्या सीमा के भीतर है, तो सुरुचिपूर्ण ढंग से कैसे जांचें?


157

मैं इसे C # और .NET 3.5 / 4 के साथ कैसे कर सकता हूं?

उदाहरण के लिए, एक संख्या 1 और 100 के बीच हो सकती है।

मुझे पता होगा कि अगर कोई आसान होता है; लेकिन इस सवाल का कीवर्ड लालित्य है। यह मेरी खिलौना परियोजना के लिए है न कि उत्पादन के लिए।

यह प्रश्न गति के बारे में नहीं था, बल्कि कोड सौंदर्य के बारे में था। दक्षता और इस तरह की बातें करना बंद करें; याद रखें कि आप गाना बजानेवालों को उपदेश दे रहे हैं।


23
पुन: आपका "संपादित" - सरल सुरुचिपूर्ण है । मैं व्यक्तिगत रूप से इस कथन को करने के किसी भी गैर-मानक साधनों की तुलना में अधिक सुरुचिपूर्ण होने पर ...
रीड कोपसे जूल 6'10

4
"सब कुछ जितना संभव हो उतना सरल बनाया जाना चाहिए, लेकिन सरल नहीं।" - अल्बर्ट आइंस्टीन
corsiKa

3
@ शेरगियो: मुझे नहीं लगता कि मुझे पांडित्य हो रहा है। मुझे लगता है कि लोग पहले से ही सरल होने वाली चीजों को बदलने के लिए भाषा में विस्तार के तरीकों और अन्य साधनों का दुरुपयोग करते हैं। दो अंतर मूल्यों की तुलना करने के सैकड़ों तरीके हैं, लेकिन कुछ का उपयोग करके लेकिन अधिक स्पष्ट एक खराब विकल्प है, आईएमओ।
रीड कोपसे जूल 6'10

3
@ शेरगियो: मुझे लगता है, फिर, मैं सवाल का मुद्दा नहीं देख रहा हूँ;)
रीड

6
@ शेरगियो: अगर if"बारोक" ठीक नहीं है।
स्ट्रिपिंगवर्यर

जवाबों:


154

बहुत सारे विकल्प हैं:

int x = 30;
if (Enumerable.Range(1,100).Contains(x))
    //true

if (x >= 1 && x <= 100)
    //true

इसके अलावा, रेगेक्स विकल्पों के लिए इस एसओ पोस्ट को देखें।


334
Enumerable.Range को पहले पूर्णांक की गणना करनी होती है, और फिर उसे खोजने के लिए प्रत्येक आइटम पर लूप करना होता है। किसी मूल्य की जाँच करने की तुलना में यह एक भयानक विचार और प्रदर्शन है जो बहुत भिन्न है। मुझे लगता है कि हमें एक मोटो अपनाना चाहिए, सिर्फ इसलिए कि LINQ एक्सटेंशन्स शांत हैं, इसका मतलब यह नहीं है कि उन्हें हर चीज के लिए इस्तेमाल किया जाना चाहिए।
मैथ्यू एबट


15
मैं मानता हूं कि यह एक भयानक विचार प्रदर्शन-वार है, लेकिन ओपी एक ifबयान की तुलना में कुछ अधिक फैंसी चाहता है । यह निश्चित रूप से पूरा करता है कि ...;)
टिम कोकर

10
यह ध्यान देने योग्य है कि दूसरा पैरामीटर "स्टॉप" नहीं है, लेकिन "काउंट" है। उदाहरण के लिए, Enumerable.Range (150, 300) ।कंटेनर (400) सही लौटेगा।
शतुर

5
कृपया इस उत्तर का उपयोग न करें । यदि आपकी पर्वतमाला काफी बड़ी है तो इसका भयावह प्रदर्शन होगा। कृपया उत्तर देखें @ olivier-jacot-descombes
Aaron Hudon

95

क्या मतलब है आपका?

if(number >= 1 && number <= 100)

या

bool TestRange (int numberToCheck, int bottom, int top)
{
  return (numberToCheck >= bottom && numberToCheck <= top);
}

1
आपको "वहाँ" की आवश्यकता नहीं है ... यह संकलन नहीं करेगा। (अन्यथा, मैं 100% सहमत हूं)
रीड कोपसे जूल

4
@, बस जब तक मैं कोशिश करूँ और इसे पेटेंट कराऊँ, तब तक प्रतीक्षा करें :)
kemiller2002

मुझे लगता है कि यह सबसे ठोस समाधान है, लेकिन नहीं है कि सुरुचिपूर्ण ढंग से प्रश्नकर्ता की तलाश है, है ना?
केविन सरल

केवल एक चीज जो मैं बदलूंगा वह है स्टैटिक कीवर्ड को विधि में जोड़ना। ;-)
रॉबर्ट एस।

सीमा बनाम झंडे, अर्थात InRange (संख्या, लोअर बाउंड, LOWER_IS_INCLUSIVE, ऊपरी, UPPER_IS_EXCLUSIVE) <बनाम <= के लिए अनुमति देने के लिए। मैंने इसे स्पष्ट करने के इरादे से लिखा था लेकिन अब जब मुझे लगता है कि इसके बारे में झंडे वास्तव में कॉलर को अपने विनिर्देश सीधे प्राप्त करने के लिए प्रोत्साहित करेंगे।
विलियम टी। मल्लार्ड

56

यहाँ शोर में जोड़ने के लिए, आप एक विस्तार विधि बना सकते हैं:

public static bool IsWithin(this int value, int minimum, int maximum)
{
    return value >= minimum && value <= maximum;
}

जो आपको कुछ ऐसा करने देगा ...

int val = 15;

bool foo = val.IsWithin(5,20);

यह कहा जा रहा है, यह एक मूर्खतापूर्ण बात की तरह लगता है जब चेक केवल एक ही लाइन है।


1
@ बान: मैं उस विषय पर गया था, जो कहता है "एक सीमा के भीतर" (जो मुझे नहीं लगता कि उस संबंध में अस्पष्ट है), लेकिन आप सही हैं कि प्रश्न निकाय "1 और 100 के बीच" कहता है (जो , ज़ाहिर है, अस्पष्ट)।
एडम रॉबिन्सन

48

जैसा कि दूसरों ने कहा, अगर एक सरल का उपयोग करें।

आपको ऑर्डर देने के बारे में सोचना चाहिए।

जैसे

1 <= x && x <= 100

से पढ़ना आसान है

x >= 1 && x <= 100

19
"आसान" देखने वाले की नजर में है। मैं व्यक्तिगत रूप से बाईं ओर के प्रश्न में चर को पसंद करता हूं और निरंतर या चर को दाईं ओर के प्रश्न में नहीं
एडम रॉबिन्सन

15
में पर्ल 6 , आप लिखते थे 1 <= x <= 100
जोर्डो

2
संख्या रेखा क्रम शुरू में सबसे स्पष्ट है - लेकिन आप अन्य आदेशों के लिए अपनी आंखों / दिमाग को प्रशिक्षित कर सकते हैं। विशेष रूप से - मुझे हमेशा बाईं ओर स्थिर रखने की चाल पसंद है । यदि आप ऐसा करते हैं, तो कंपाइलर आपको बताएगा कि आपने =इसके बजाय कब टाइप किया है ==। यह गैर-समानता रिलेशनल ऑपरेटरों के साथ मदद नहीं करता है - लेकिन इसे लगातार उपयोग करने की आदत डालना आसान है।
दविबक

1
मैं सिर्फ यह जोड़ना चाहता हूं कि यह समाधान किसी भी मामले में उपयोगी नहीं है। विचार xएक जटिल फ़ंक्शन कॉल या समय लेने वाली लाइनक-अभिव्यक्ति है। इस मामले में आप दो बार ऐसा करेंगे जो अच्छी बात नहीं है। सुनिश्चित करें कि आपको एक अस्थायी स्थानीय चर में मूल्य को संग्रहीत करना चाहिए लेकिन कुछ मामले हैं (उदाहरण के लिए-यदि-यदि-कथन) तो आप केवल अन्य कार्यों को कॉल करना चाहते हैं यदि अन्य है या नहीं-यदि विफल है। अस्थायी चर के साथ आपको पहले भी उन्हें कॉल करना होगा। एक विस्तार विधि (अन्य उत्तरों में उल्लिखित) उन मामलों में सबसे अच्छा समाधान इम्हो है।
रॉबर्ट एस।

4
मुझे संख्या रेखा क्रम भी पसंद है, और पूरक परीक्षण के लिए भी, जैसे x <10 || 20 <एक्स। मेरे लिए यह चिल्लाता है "x 10 - 20 की सीमा के बाहर है"।
विलियम टी। मल्लार्ड

44

उत्पादन कोड में मैं बस लिखूंगा

1 <= x && x <= 100

यह समझने में आसान है और बहुत पठनीय है।


यहां एक चतुर विधि है जो कुछ गणित का उपयोग करके तुलनाओं की संख्या को दो से एक तक कम कर देती है। यह विचार है कि दो में से एक कारक ऋणात्मक हो जाता है यदि संख्या सीमा के बाहर होती है और शून्य यदि संख्या एक सीमा के बराबर है:

यदि सीमाएं सम्मिलित हैं:

(x - 1) * (100 - x) >= 0

या

(x - min) * (max - x) >= 0

यदि सीमाएँ अनन्य हैं:

(x - 1) * (100 - x) > 0

या

(x - min) * (max - x) > 0

3
मेरे मानकों से यह अब तक का सबसे सुरुचिपूर्ण समाधान है, दिलचस्प यह है कि मेरे लिए यह दोनों अभिव्यक्तियों की जांच करने की तुलना में कुछ तेज दौड़ता हुआ प्रतीत होता है, कहा कि यह भी अधिक असंगत लगता है (गति अधिक बदलती प्रतीत होती है) देखना दिलचस्प होगा यदि कोई शोध हो, जिस पर कोई तेजी से हो।
थॉमस लिंडवैल

3
जावास्क्रिप्ट पर अपने समाधान का परीक्षण किया और 14-दशमलव तक फ्लोटिंग-पॉइंट संख्याओं के साथ इसका सटीक। यह एक बहुत अच्छा कोड स्निपेट है। अगर मैं कर सकता, तो यह आपको तीन बार ऊपर
उठाता

4
हालाँकि, एक छोटी सी समस्या है यदि बड़ी सकारात्मक संख्याएं शामिल हैं, तो यह अतिप्रवाह कर सकती है! XD आप अपना कोड लिखते समय इसे ध्यान में रखना चाह सकते हैं।
BrainStorm.exe

2
सवाल लालित्य के लिए पूछता है और इसलिए व्यावहारिक मूल्य से अधिक अकादमिक है। व्यक्तिगत रूप से मैं सिर्फ एक साधारण 1 < x && x < 100उत्पादक कोड का उपयोग करूंगा । इसे समझना आसान है।
ओलिवियर जैकोत-डेसकॉम्बस

1
प्रदर्शन के बारे में चिंतित लोगों के लिए, 1 < x & x < 100(कोई और & lt; शॉर्ट सर्किट) संकलक को निर्देश देता है कि वह हमेशा मूल्यांकन कर x < 100सकता है, जिसके परिणाम का कोई फर्क नहीं पड़ता 1 < x। अजीब तरह से (शाखा की भविष्यवाणी के कारण) यह कभी-कभी इसे छोड़ना है, की तुलना में यह सरल ऑपरेशन करना हमेशा तेज़ होता है।
टॉम लीज

23

मैं यह प्रस्ताव करता हूं:

public static bool IsWithin<T>(this T value, T minimum, T maximum) where T : IComparable<T> {
    if (value.CompareTo(minimum) < 0)
       return false;
    if (value.CompareTo(maximum) > 0)
       return false;
    return true;
}

उदाहरण:

45.IsWithin(32, 89)
true
87.2.IsWithin(87.1, 87.15)
false
87.2.IsWithin(87.1, 87.25)
true

और निश्चित रूप से चर के साथ:

myvalue.IsWithin(min, max)

यह पढ़ना आसान है (मानव भाषा के करीब) और किसी भी तुलनीय प्रकार (पूर्णांक, डबल, कस्टम प्रकार ...) के साथ काम करता है।

कोड को पढ़ने में आसान होना महत्वपूर्ण है क्योंकि डेवलपर इसे समझने के लिए "मस्तिष्क चक्र" को बर्बाद नहीं करेगा। लंबे कोडिंग सत्रों में व्यर्थ मस्तिष्क चक्र पहले डेवलपर को थका देते हैं और बग से ग्रस्त हो जाते हैं।


3
मैं इस शब्द के बीच का उपयोग करके और भी अधिक सरल बना सकता हूँ, और यह निर्धारित करने के लिए कि क्या समावेशी है या नहीं
बेन

अच्छा। यह समझना आसान है। मैंने नाम बदल दिया है IsInRange. I'm not that keen on Ben's inclusive boolean as that requires a few more brain cycles. It has the advantage that it can be used in any class that that implements IComparer. This is in my Extensions now along with LiesWithin / LiesInside. Just can't decide which. NotOutside काम करेगा, लेकिन मुझे नकारात्मक परिस्थितियां पसंद नहीं हैं
पॉलिटेक्स्टस

21

विस्तार पद्धति के दुरुपयोग के साथ, हम निम्नलिखित "सुरुचिपूर्ण" समाधान प्राप्त कर सकते हैं:

using System;

namespace Elegant {
    public class Range {
        public int Lower { get; set; }
        public int Upper { get; set; }
    }

    public static class Ext {
        public static Range To(this int lower, int upper) {
            return new Range { Lower = lower, Upper = upper };
        }

        public static bool In(this int n, Range r) {
            return n >= r.Lower && n <= r.Upper;
        }
    }

    class Program {
        static void Main() {
            int x = 55;
            if (x.In(1.To(100)))
                Console.WriteLine("it's in range! elegantly!");
        }
    }
}

समाधान की तरह! Btw समावेशी समर्थन करने के लिए, बनाने के enum Inclusiveमूल्यों के साथ: Lower, Upper, All। और Inफ़ंक्शन के लिए enum Inclusiveडिफ़ॉल्ट मान के साथ एक अतिरिक्त प्रकार का पैरामीटर पास करेंInclusive.All , अद्यतन Toसंभाल करने के लिए समारोह शरीर All, Lower, Upperमूल्यों :)
निकिता

7

यदि यह आकस्मिक है, तो एक साधारण ifआपकी ज़रूरत है। यदि यह कई स्थानों पर होता है, तो आप इन दोनों पर विचार करना चाहते हैं:

  • PostSharp । उन विशेषताओं के साथ तरीकों को सजाएं जो संकलन के बाद विधि में 'इंजेक्ट' कोड करते हैं। मुझे यकीन नहीं है, लेकिन मैं सोच सकता हूं कि इसके लिए इसका इस्तेमाल किया जा सकता है।

कुछ इस तरह:

[Between("parameter", 0, 100)]
public void Foo(int parameter)
{
}
  • कोड अनुबंध । क्या फायदा है कि आपके कोड के स्थैतिक सत्यापन और आपके कोड का उपयोग करने वाले स्थानों से, बाधाओं का संकलन समय पर जाँच की जा सकती है।

कोड अनुबंध के लिए +1; यह एक पैरामीटर को मान्य करने के लिए विशिष्ट है, लेकिन यह लगातार उपयोग का मामला है और स्थैतिक सत्यापन में अत्यंत उपयोगी होने की क्षमता है।
दान ब्रायंट


5

&&दो तुलनाओं में शामिल होने के लिए एक अभिव्यक्ति का उपयोग करना ऐसा करने का सबसे सुंदर तरीका है। यदि आप फैंसी एक्सटेंशन विधियों और इस तरह का उपयोग करने की कोशिश करते हैं, तो आप इस सवाल में भागते हैं कि क्या ऊपरी सीमा, निम्न सीमा, या दोनों को शामिल करना है या नहीं। एक बार जब आप अतिरिक्त चर जोड़ना शुरू कर देते हैं या जो शामिल है उसे इंगित करने के लिए एक्सटेंशन नामों को बदलना शुरू करते हैं, तो आपका कोड पढ़ने के लिए लंबा और कठिन हो जाता है (अधिकांश प्रोग्रामर के लिए)। इसके अलावा, अगर आपकी तुलना का कोई मतलब नहीं है, तो Resharper जैसे उपकरण आपको चेतावनी देंगे (number > 100 && number < 1 नहीं है, तो रेसहरपर जो कि आप ऐसा नहीं करेंगे यदि आप एक विधि का उपयोग करते हैं ('i.IsBetween (100, 1)')।

केवल एक और टिप्पणी मैं यह करूंगा कि यदि आप अपवाद को फेंकने के इरादे से इनपुट की जाँच कर रहे हैं, तो आपको कोड अनुबंधों का उपयोग करने पर विचार करना चाहिए:

Contract.Requires(number > 1 && number < 100)

यह तुलना में अधिक सुरुचिपूर्ण है if(...) throw new Exception(...), और यदि आप किसी को यह सुनिश्चित करने के बिना कि आपके नंबर को पहले सीमा में है, तो कॉल करने की कोशिश करने पर भी संकलन-समय की चेतावनी मिल सकती है।


2
FYI, कॉन्ट्रैक्टिक स्टैटिक एनालाइज़र तब अधिक खुश होता है जब निचले बाउंड और अपर बाउंड कंस्ट्रक्शन को अलग-अलग स्टेटमेंट में विभाजित किया जाता है।
दान ब्रायंट

धन्यवाद Dan ब्रायंट, ठीक है कि मैं यहाँ क्या देख रहा था। आवश्यकता और अन्य संबंधित कोड अनुबंध विधियों के लिए शर्तों की शैली के सुझावों पर बहुत अधिक सामग्री नहीं मिल सकती है।
जिपरसन

2

यदि आप एक सरल से अधिक कोड लिखना चाहते हैं, तो शायद आप कर सकते हैं: IsBetween नामक एक एक्सटेंशन विधि बनाएं

public static class NumberExtensionMethods
{
    public static bool IsBetween(this long value, long Min, long Max)
    {
        // return (value >= Min && value <= Max);
        if (value >= Min && value <= Max) return true;
        else return false;
    }
}

...

// Checks if this number is between 1 and 100.
long MyNumber = 99;
MessageBox.Show(MyNumber.IsBetween(1, 100).ToString());

परिशिष्ट:यह ध्यान देने योग्य है कि व्यवहार में आप शायद ही कभी "समानता के लिए जांचते हैं" (या <,>) एक कोडबेस में। (सबसे तुच्छ परिस्थितियों में अन्य।) विशुद्ध रूप से एक उदाहरण के रूप में, कोई भी गेम प्रोग्रामर प्रत्येक परियोजना में निम्नलिखित चीजों की तरह श्रेणियों का उपयोग करेगा, एक मूल मामले के रूप में। ध्यान दें कि इस उदाहरण में यह (ऐसा होता है) एक फ़ंक्शन (Mathf.Approximately) का उपयोग करके जो उस वातावरण में बनाया गया है; व्यवहार में, आपको आमतौर पर अपनी स्वयं की अवधारणाओं को ध्यान से विकसित करना होगा कि वास्तविक संख्याओं के कंप्यूटर अभ्यावेदन के लिए तुलना का क्या मतलब है, जिस प्रकार की स्थिति आपके लिए इंजीनियरिंग है। (यह भी उल्लेख न करें कि यदि आप ऐसा कुछ कर रहे हैं, तो शायद एक नियंत्रक, एक पीआईडी ​​नियंत्रक या जैसे, पूरा मुद्दा केंद्रीय और बहुत कठिन हो जाता है, यह परियोजना की प्रकृति बन जाती है।

private bool FloatLessThan(float a, float b)
    {
    if ( Mathf.Approximately(a,b) ) return false;
    if (a<b) return true;
    return false;
    }

private bool FloatLessThanZero(float a)
    {
    if ( Mathf.Approximately(a,0f) ) return false;
    if (a<0f) return true;
    return false;
    }

private bool FloatLessThanOrEqualToZero(float a)
    {
    if ( Mathf.Approximately(a,0f) ) return true;
    if (a<0f) return true;
    return false;
    }

1
अगर और के साथ बदलेंreturn (value >= Min && value <= Max);
AeroX

तुलना लिखने का सुंदर तरीका है "तार्किक क्रम में ..." यदि (न्यूनतम <= मान और& मूल्य <= अधिकतम)। यह बहुत सुंदर है।
फेटी

2
इस सवाल पर आगे, यह बहुत आश्चर्यजनक है कि किसी ने भी किसी वास्तविक दुनिया की परियोजना में केंद्रीय मुद्दे का उल्लेख नहीं किया है (विशेषकर यदि आप एक गेम इंजीनियर हैं) तो यह है कि आपको सन्निकटन समस्या से निपटना होगा । किसी भी वास्तविक दुनिया के सॉफ्टवेयर में आप अनिवार्य रूप से "बस एक तुलना करते हैं" (चाहे समानता या <,>) आपको हाथ में स्थिति के आधार पर, त्रुटि मुद्दे से संबंधित और विचार करना होगा। मैंने इस उत्तर के लिए एक परिशिष्ट में संपादित किया है (केवल सही उत्तर यहाँ!) क्योंकि कोई और उत्तर की अनुमति नहीं है।
फेटी

इस अवलोकन और परिशिष्ट के लिए धन्यवाद।
टोनी

2

क्योंकि अन्य सभी उत्तर मेरे द्वारा आविष्कार नहीं किए गए हैं, यहाँ सिर्फ मेरा कार्यान्वयन है:

public enum Range
{
    /// <summary>
    /// A range that contains all values greater than start and less than end.
    /// </summary>
    Open,
    /// <summary>
    /// A range that contains all values greater than or equal to start and less than or equal to end.
    /// </summary>
    Closed,
    /// <summary>
    /// A range that contains all values greater than or equal to start and less than end.
    /// </summary>
    OpenClosed,
    /// <summary>
    /// A range that contains all values greater than start and less than or equal to end.
    /// </summary>
    ClosedOpen
}

public static class RangeExtensions
{
    /// <summary>
    /// Checks if a value is within a range that contains all values greater than start and less than or equal to end.
    /// </summary>
    /// <param name="value">The value that should be checked.</param>
    /// <param name="start">The first value of the range to be checked.</param>
    /// <param name="end">The last value of the range to be checked.</param>
    /// <returns><c>True</c> if the value is greater than start and less than or equal to end, otherwise <c>false</c>.</returns>
    public static bool IsWithin<T>(this T value, T start, T end) where T : IComparable<T>
    {
        return IsWithin(value, start, end, Range.ClosedOpen);
    }

    /// <summary>
    /// Checks if a value is within the given range.
    /// </summary>
    /// <param name="value">The value that should be checked.</param>
    /// <param name="start">The first value of the range to be checked.</param>
    /// <param name="end">The last value of the range to be checked.</param>
    /// <param name="range">The kind of range that should be checked. Depending on the given kind of range the start end end value are either inclusive or exclusive.</param>
    /// <returns><c>True</c> if the value is within the given range, otherwise <c>false</c>.</returns>
    public static bool IsWithin<T>(this T value, T start, T end, Range range) where T : IComparable<T>
    {
        if (value == null)
            throw new ArgumentNullException(nameof(value));

        if (start == null)
            throw new ArgumentNullException(nameof(start));

        if (end == null)
            throw new ArgumentNullException(nameof(end));

        switch (range)
        {
            case Range.Open:
                return value.CompareTo(start) > 0
                       && value.CompareTo(end) < 0;
            case Range.Closed:
                return value.CompareTo(start) >= 0
                       && value.CompareTo(end) <= 0;
            case Range.OpenClosed:
                return value.CompareTo(start) > 0
                       && value.CompareTo(end) <= 0;
            case Range.ClosedOpen:
                return value.CompareTo(start) >= 0
                       && value.CompareTo(end) < 0;
            default:
                throw new ArgumentException($"Unknown parameter value {range}.", nameof(range));
        }
    }
}

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

var value = 5;
var start = 1;
var end = 10;

var result = value.IsWithin(start, end, Range.Closed);

2

संपादित करें: नया उत्तर प्रदान किया गया। मैं अभी C # का उपयोग करना शुरू कर रहा था, जब मैंने इस प्रश्न का पहला उत्तर लिखा था, और इस दृष्टि से मुझे अब पता चला कि मेरा "समाधान" भोला और अक्षम था।

मेरा मूल उत्तर: मैं अधिक सरल संस्करण के साथ जाऊंगा:

if(Enumerable.Range(1,100).Contains(intInQuestion)) { ...DoStuff; }

एक बेहतर तरीका

जैसा कि मैंने कोई अन्य समाधान नहीं देखा है जो अधिक कुशल है (कम से कम मेरे परीक्षणों के अनुसार), मैं इसे एक और जाने दूंगा।

नया और बेहतर तरीका जो नकारात्मक सीमाओं के साथ भी काम करता है :

// Returns true if x is in range [min..max], else false 
bool inRange(int x, int min=1, int max=100) => ((x - max)*(x - min) <= 0);

इसका उपयोग सकारात्मक और नकारात्मक दोनों श्रेणियों के साथ किया जा सकता है और कई प्रकार की चूक हो सकती हैं

1..100 (समावेशी) और xएक वैकल्पिक श्रेणी द्वारा जाँच करने के लिए संख्या के रूप में उपयोग करता है minऔर द्वारा परिभाषित max

अच्छे उपाय के लिए उदाहरण जोड़ना

उदाहरण 1:

// Returns true if x is in range [min..max], else false 
bool inRange(int x, int min=1, int max=100) => ((x - max)*(x - min) <= 0);

Console.WriteLine(inRange(25));
Console.WriteLine(inRange(1));
Console.WriteLine(inRange(100));
Console.WriteLine(inRange(25, 30, 150));
Console.WriteLine(inRange(-25, -50, 0));

यह दिखाता है:

True
True
True
False
True

उदाहरण 2: 1 और 150 के बीच यादृच्छिक ints की सूची का उपयोग करना

// Returns true if x is in range [min..max], else false 
bool inRange(int x, int min=1, int max=100) => ((x - max)*(x - min) <= 0);

// Generate 100000 ints between 1 and 150
var intsToCheck = new List<int>();
var randGen = new Random();
for(int i = 0; i < 100000; ++i){
    intsToCheck.Add(randGen.Next(150) + 1);
}

var counter = 0;
foreach(int n in intsToCheck) {
    if(inRange(n)) ++counter;
}

Console.WriteLine("{0} ints found in range 1..100", counter);

यह दिखाता है:

66660 ints found in range 1..100

निष्पादन समय: 0.016 सेकंड (s)


हाँ, मैं 2013 से मेरे उत्तर के लिए एक टिप्पणी पर टिप्पणी कर रहा हूं :) @RyanTheLeach: इस सवाल का मेरा जवाब अब "स्वीकृत" उत्तर से अलग कैसे है? मुझे पता है कि यह सबसे प्रभावी ट्रावेल नहीं है, लेकिन "भयानक" है? 100 ints के माध्यम से आवंटन और लूपिंग कितना बुरा हो सकता है? 1950 में शायद इसे सामाजिक रूप से स्वीकार नहीं किया गया था, लेकिन ...
19

@RyanTheLeach मैं आपको दोष नहीं देता ... मैंने अपना जवाब अपडेट कर दिया है, इसलिए, यदि आप एक ऐसे समाधान के बारे में जानते हैं जो और भी अधिक कुशल है, तो कृपया विस्तृत करें!
crewer

1
मैंने अपनी टिप्पणियों को हटा दिया है क्योंकि वे अब खड़ी नहीं हैं। ठीक करने के लिए धन्यवाद, यह ठीक लगता है।
रयान द लीच

1

एक पुराने पसंदीदा पर एक नया मोड़:

public bool IsWithinRange(int number, int topOfRange, int bottomOfRange, bool includeBoundaries) {
    if (includeBoundaries)
        return number <= topOfRange && number >= bottomOfRange;
    return number < topOfRange && number > bottomOfRange;
}

3
वास्तव में चार मामले हैं, समावेशी / समावेशी, समावेशी / अनन्य, अनन्य / समावेशी और अनन्य / अनन्य।
विलियम टी। मलार्ड

1

सी में, अगर समय दक्षता महत्वपूर्ण है और पूर्णांक ओवरफ्लो लपेटेंगे, तो कोई भी कर सकता है if ((unsigned)(value-min) <= (max-min)) ...। यदि 'अधिकतम' और 'मिनट' स्वतंत्र चर हैं, तो (अधिकतम-मिनट) के लिए अतिरिक्त घटाव समय बर्बाद करेगा, लेकिन अगर उस अभिव्यक्ति को संकलन समय पर पूर्व-निर्धारित किया जा सकता है, या यदि इसे एक बार चलाने के लिए कई बार परीक्षण करने के लिए गणना की जा सकती है समान श्रेणी के विरुद्ध संख्या, उपरोक्त अभिव्यक्ति कुशलता से उस स्थिति में भी गणना की जा सकती है, जहां मूल्य सीमा के भीतर है (यदि मानों का एक बड़ा अंश मान्य सीमा से नीचे होगा, तो इसका उपयोग करना तेज़ हो सकता है if ((value >= min) && (value <= max)) ...क्योंकि यह मान से जल्दी बाहर निकल जाएगा मिनट से कम है)।

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


1

इस जैसे किसी और के बारे में क्या राय है?

if (theNumber.isBetween(low, high, IntEx.Bounds.INCLUSIVE_INCLUSIVE))
{
}

विस्तार विधि के साथ निम्नानुसार (परीक्षण):

public static class IntEx
{
    public enum Bounds 
    {
        INCLUSIVE_INCLUSIVE, 
        INCLUSIVE_EXCLUSIVE, 
        EXCLUSIVE_INCLUSIVE, 
        EXCLUSIVE_EXCLUSIVE
    }

    public static bool isBetween(this int theNumber, int low, int high, Bounds boundDef)
    {
        bool result;
        switch (boundDef)
        {
            case Bounds.INCLUSIVE_INCLUSIVE:
                result = ((low <= theNumber) && (theNumber <= high));
                break;
            case Bounds.INCLUSIVE_EXCLUSIVE:
                result = ((low <= theNumber) && (theNumber < high));
                break;
            case Bounds.EXCLUSIVE_INCLUSIVE:
                result = ((low < theNumber) && (theNumber <= high));
                break;
            case Bounds.EXCLUSIVE_EXCLUSIVE:
                result = ((low < theNumber) && (theNumber < high));
                break;
            default:
                throw new System.ArgumentException("Invalid boundary definition argument");
        }
        return result;
    }
}

1

मैं एक रेंज ऑब्जेक्ट, कुछ इस तरह से करूंगा:

public class Range<T> where T : IComparable
{
    public T InferiorBoundary{get;private set;}
    public T SuperiorBoundary{get;private set;}

    public Range(T inferiorBoundary, T superiorBoundary)
    {
        InferiorBoundary = inferiorBoundary;
        SuperiorBoundary = superiorBoundary;
    }

    public bool IsWithinBoundaries(T value){
        return InferiorBoundary.CompareTo(value) > 0 && SuperiorBoundary.CompareTo(value) < 0;
    }
}

तो आप इसे इस तरह से उपयोग करें:

Range<int> myRange = new Range<int>(1,999);
bool isWithinRange = myRange.IsWithinBoundaries(3);

इस तरह से आप इसे दूसरे प्रकार के लिए पुन: उपयोग कर सकते हैं।


आपके Rangeऑब्जेक्ट को CompareToआइटम की तुलना करने के लिए विधि का उपयोग करने की आवश्यकता है , <ऑपरेटर नहीं ।
सेवी

यदि आप IComparable को लागू कर रहे हैं, तो आप सही हैं, आपको ऑपरेटरों को भी ओवरराइड करना चाहिए (कम से कम यही मेरा VS कोड विश्लेषण कह रहा है), जिसका अर्थ है <काम करेगा। हालांकि मैं गलत हो सकता हूं, मुझे ज्यादा अनुभव नहीं है और यह SO पर मेरा पहला जवाब है
IEatBagels

नहीं, आपका कंपाइलर यह नहीं कहेगा कि यह काम करता है। यह संकलन नहीं होगा। किसी ऑब्जेक्ट को लागू करने IComparableऔर <ऑपरेटर को अधिभार नहीं देने के लिए यह पूरी तरह से उचित है ।
सेवि

1

यह जांचने पर कि क्या "संख्या" एक सीमा में है, आपको स्पष्ट होना चाहिए कि आपका क्या मतलब है, और दो संख्याओं का क्या मतलब है? सामान्य तौर पर आपको सभी फ़्लोटिंग पॉइंट नंबरों को लपेटना चाहिए, जिन्हें 'एप्सिलॉन बॉल' कहा जाता है, यह कुछ छोटे मानों को उठाकर किया जाता है और कहा जाता है कि यदि दो मान इस नज़दीकी हैं तो वे एक ही चीज़ हैं।

    private double _epsilon = 10E-9;
    /// <summary>
    /// Checks if the distance between two doubles is within an epsilon.
    /// In general this should be used for determining equality between doubles.
    /// </summary>
    /// <param name="x0">The orgin of intrest</param>
    /// <param name="x"> The point of intrest</param>
    /// <param name="epsilon">The minimum distance between the points</param>
    /// <returns>Returns true iff x  in (x0-epsilon, x0+epsilon)</returns>
    public static bool IsInNeghborhood(double x0, double x, double epsilon) => Abs(x0 - x) < epsilon;

    public static bool AreEqual(double v0, double v1) => IsInNeghborhood(v0, v1, _epsilon);

इन दो सहायकों के स्थान पर और यह मानते हुए कि यदि आवश्यक सटीकता के बिना किसी भी संख्या को दोहरे के रूप में डाला जा सकता है। अब आपको केवल एक एनम और एक अन्य विधि की आवश्यकता होगी

    public enum BoundType
    {
        Open,
        Closed,
        OpenClosed,
        ClosedOpen
    }

अन्य विधि इस प्रकार है:

    public static bool InRange(double value, double upperBound, double lowerBound, BoundType bound = BoundType.Open)
    {
        bool inside = value < upperBound && value > lowerBound;
        switch (bound)
        {
            case BoundType.Open:
                return inside;
            case BoundType.Closed:
                return inside || AreEqual(value, upperBound) || AreEqual(value, lowerBound); 
            case BoundType.OpenClosed:
                return inside || AreEqual(value, upperBound);
            case BoundType.ClosedOpen:
                return inside || AreEqual(value, lowerBound);
            default:
                throw new System.NotImplementedException("You forgot to do something");
        }
    }

अब यह जो आप चाहते थे उससे कहीं अधिक हो सकता है, लेकिन यह आपको हर समय चक्कर लगाने से बचाता है और यह याद रखने की कोशिश करता है कि क्या मूल्य गोल किया गया है और किस स्थान पर है। अगर आपको जरूरत है तो आप किसी भी एप्सिलॉन के साथ काम करने और अपने एप्सिलॉन को बदलने की अनुमति देने के लिए इसे आसानी से बढ़ा सकते हैं।


1
static class ExtensionMethods
{
    internal static bool IsBetween(this double number,double bound1, double bound2)
    {
        return Math.Min(bound1, bound2) <= number && number <= Math.Max(bound2, bound1);
    }

    internal static bool IsBetween(this int number, double bound1, double bound2)
    {
        return Math.Min(bound1, bound2) <= number && number <= Math.Max(bound2, bound1);
    }
}

प्रयोग

डबल नंबरटैबचेक = 7;

var result = numberToBeChecked.IsBetween (100,122);

var परिणाम = 5.IsBetween (100,120);

var परिणाम = 8.0.IsBetween (1.2,9.6);


1

यदि आप स्वीकृत उत्तर पर @Daap द्वारा टिप्पणी से चिंतित हैं और केवल एक बार मान पास कर सकते हैं, तो आप निम्न में से एक का प्रयास कर सकते हैं

bool TestRangeDistance (int numberToCheck, int bottom, int distance)
{
  return (numberToCheck >= bottom && numberToCheck <= bottom+distance);
}

//var t = TestRangeDistance(10, somelist.Count()-5, 10);

या

bool TestRangeMargin (int numberToCheck, int target, int margin)
{
  return (numberToCheck >= target-margin && numberToCheck <= target+margin);
}

//var t = TestRangeMargin(10, somelist.Count(), 5);

1

लालित्य के बारे में, गणितीय संकेतन की निकटतम चीज़ ( <= x <= b ) पठनीयता में थोड़ा सुधार करती है:

public static bool IsBetween(this int value, int min, int max)
{
    return min <= value && value <= max;
}

आगे चित्रण के लिए:

public static bool IsOutside(this int value, int min, int max)
{
    return value < min || max < value;
}

0

मैं इसे करने के लिए एक सुरुचिपूर्ण तरीके की तलाश कर रहा था जहां सीमाएं स्विच की जा सकती हैं (यानी यह सुनिश्चित नहीं है कि मान किस क्रम में हैं)।

यह केवल C # के नए संस्करणों पर काम करेगा, जहां मौजूद है ?: मौजूद है

bool ValueWithinBounds(float val, float bounds1, float bounds2)
{
    return bounds1 >= bounds2 ?
      val <= bounds1 && val >= bounds2 : 
      val <= bounds2 && val >= bounds1;
}

जाहिर है आप अपने उद्देश्यों के लिए वहां के संकेतों को बदल सकते हैं। टाइप कास्टिंग के साथ फैंसी भी मिल सकता है। मुझे बस सीमा के भीतर एक फ्लोट वापसी की आवश्यकता थी (या इसके बराबर)


0

सुरुचिपूर्ण इसलिए क्योंकि आपको यह निर्धारित करने की आवश्यकता नहीं है कि दोनों में से कौन सा सीमा मूल्य पहले से अधिक है। इसमें कोई शाखाएं भी नहीं हैं।

public static bool InRange(float val, float a, float b)
{
    // Determine if val lies between a and b without first asking which is larger (a or b)
    return ( a <= val & val < b ) | ( b <= val & val < a );
}

& + | बिटवाइज़ ऑपरेटर हैं
nelsontruran

0

मुझे नहीं पता लेकिन मैं इस विधि का उपयोग करता हूं:

    public static Boolean isInRange(this Decimal dec, Decimal min, Decimal max, bool includesMin = true, bool includesMax = true ) {

    return (includesMin ? (dec >= min) : (dec > min)) && (includesMax ? (dec <= max) : (dec < max));
}

और यह वह तरीका है जिससे मैं इसका उपयोग कर सकता हूं:

    [TestMethod]
    public void IsIntoTheRange()
    {
        decimal dec = 54;

        Boolean result = false;

        result = dec.isInRange(50, 60); //result = True
        Assert.IsTrue(result);

        result = dec.isInRange(55, 60); //result = False
        Assert.IsFalse(result);

        result = dec.isInRange(54, 60); //result = True
        Assert.IsTrue(result);

        result = dec.isInRange(54, 60, false); //result = False
        Assert.IsFalse(result);

        result = dec.isInRange(32, 54, false, false);//result = False
        Assert.IsFalse(result);

        result = dec.isInRange(32, 54, false);//result = True
        Assert.IsTrue(result);
    }

कृपया कोड ब्लॉक के नीचे उपयोग का एक उदाहरण प्रदान करें, यह ओपी को यह जानने में मदद करेगा कि क्या वह अपने उद्देश्य को पूरा करता है
गेब्रियल बाल्सा कैंटु

0

ये कुछ विस्तार विधियाँ हैं जो मदद कर सकती हैं

  public static bool IsInRange<T>(this T value, T min, T max)
where T : System.IComparable<T>
    {
        return value.IsGreaterThenOrEqualTo(min) && value.IsLessThenOrEqualTo(max);
    }


    public static bool IsLessThenOrEqualTo<T>(this T value, T other)
         where T : System.IComparable<T>
    {
        var result = value.CompareTo(other);
        return result == -1 || result == 0;
    }


    public static bool IsGreaterThenOrEqualTo<T>(this T value, T other)
         where T : System.IComparable<T>
    {
        var result = value.CompareTo(other);
        return result == 1 || result == 0;
    }

0

यदि यह विधि मापदंडों को मान्य करने के लिए है, तो कोई भी समाधान ArgumentOutOfRangeException को नहीं फेंकता है और समावेशी / अनन्य न्यूनतम / अधिकतम मूल्यों के आसान / उचित कॉन्फ़िगरेशन की अनुमति देता है।

इस तरह का उपयोग करें

public void Start(int pos)
{
    pos.CheckRange(nameof(pos), min: 0);

    if (pos.IsInRange(max: 100, maxInclusive: false))
    {
        // ...
    }
}

मैंने सिर्फ ये सुंदर कार्य लिखे हैं। यह भी मान्य मूल्यों के लिए कोई शाखा (एक एकल यदि) होने का लाभ है। सबसे कठिन हिस्सा उचित अपवाद संदेशों को शिल्प करना है।

/// <summary>
/// Returns whether specified value is in valid range.
/// </summary>
/// <typeparam name="T">The type of data to validate.</typeparam>
/// <param name="value">The value to validate.</param>
/// <param name="min">The minimum valid value.</param>
/// <param name="minInclusive">Whether the minimum value is valid.</param>
/// <param name="max">The maximum valid value.</param>
/// <param name="maxInclusive">Whether the maximum value is valid.</param>
/// <returns>Whether the value is within range.</returns>
public static bool IsInRange<T>(this T value, T? min = null, bool minInclusive = true, T? max = null, bool maxInclusive = true)
    where T : struct, IComparable<T>
{
    var minValid = min == null || (minInclusive && value.CompareTo(min.Value) >= 0) || (!minInclusive && value.CompareTo(min.Value) > 0);
    var maxValid = max == null || (maxInclusive && value.CompareTo(max.Value) <= 0) || (!maxInclusive && value.CompareTo(max.Value) < 0);
    return minValid && maxValid;
}

/// <summary>
/// Validates whether specified value is in valid range, and throws an exception if out of range.
/// </summary>
/// <typeparam name="T">The type of data to validate.</typeparam>
/// <param name="value">The value to validate.</param>
/// <param name="name">The name of the parameter.</param>
/// <param name="min">The minimum valid value.</param>
/// <param name="minInclusive">Whether the minimum value is valid.</param>
/// <param name="max">The maximum valid value.</param>
/// <param name="maxInclusive">Whether the maximum value is valid.</param>
/// <returns>The value if valid.</returns>
public static T CheckRange<T>(this T value, string name, T? min = null, bool minInclusive = true, T? max = null, bool maxInclusive = true)
where T : struct, IComparable<T>
{
    if (!value.IsInRange(min, minInclusive, max, maxInclusive))
    {
        if (min.HasValue && minInclusive && max.HasValue && maxInclusive)
        {
            var message = "{0} must be between {1} and {2}.";
            throw new ArgumentOutOfRangeException(name, value, message.FormatInvariant(name, min, max));
        }
        else
        {
            var messageMin = min.HasValue ? GetOpText(true, minInclusive).FormatInvariant(min) : null;
            var messageMax = max.HasValue ? GetOpText(false, maxInclusive).FormatInvariant(max) : null;
            var message = (messageMin != null && messageMax != null) ?
                "{0} must be {1} and {2}." :
                "{0} must be {1}.";
            throw new ArgumentOutOfRangeException(name, value, message.FormatInvariant(name, messageMin ?? messageMax, messageMax));
        }
    }
    return value;
}

private static string GetOpText(bool greaterThan, bool inclusive)
{
    return (greaterThan && inclusive) ? "greater than or equal to {0}" :
        greaterThan ? "greater than {0}" :
        inclusive ? "less than or equal to {0}" :
        "less than {0}";
}

public static string FormatInvariant(this string format, params object?[] args) => string.Format(CultureInfo.InvariantCulture, format, args);

-2

आप ढूंढ रहे हैं in [1..100]? वह केवल पास्कल है।


2
सच नहीं है, न केवल पास्कल। कई आधुनिक भाषाओं में इस तरह की विशेषताएं हैं। उदाहरण के लिए कोटलिन में, इसे "पैटर्न मिलान" कहा जाता है। उदाहरण when (number) { in 0..9 -> println("1 digit") in 10..99 -> println("2 digits") in 100..999 -> println("3 digits") }
१५
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.