मानों की सूची के विरुद्ध चर समानता की जाँच करें


133

मैं fooकई मानों के लिए समानता के लिए एक चर की जाँच कर रहा हूं । उदाहरण के लिए,

if( foo == 1 || foo == 3 || foo == 12 ) {
    // ...
}

मुद्दा यह है कि इस तरह के एक तुच्छ कार्य के लिए यह बहुत अधिक कोड है। मैं निम्नलिखित के साथ आया:

if( foo in {1: 1, 3: 1, 12: 1} ) {
    // ...
}

लेकिन यह भी पूरी तरह से मेरे लिए अपील नहीं करता है, क्योंकि मुझे ऑब्जेक्ट में अनावश्यक मूल्यों को देना होगा।

क्या किसी को कई मूल्यों के खिलाफ समानता की जांच करने का एक सभ्य तरीका पता है?


मुझे लगता है कि इस तरह का निर्णय लेते समय बड़े संदर्भ को शामिल करने की आवश्यकता है, क्योंकि यह जानना महत्वपूर्ण है कि आप इस तरह की तुलना क्यों कर रहे हैं।
नुकीले

ठीक है, एक गेम में मैं बना रहा हूं कि मैं कीबोर्ड कोड की जांच कर रहा हूं ताकि यह तय हो सके कि किस फ़ंक्शन को बुलाया जाना चाहिए। विभिन्न ब्राउज़रों में, एक कुंजी में अलग-अलग कुंजी कोड दिखाई देते हैं, इसलिए कई मूल्यों के साथ तुलना करने की आवश्यकता होती है।
पिमवेदब

कई तरीकों के लिए प्रदर्शन परीक्षण की जाँच करें, लॉजिकल ऑपरेटर जीतता है runkit.com/pramendra/58cad911146c1c00147f8d8d
प्रमेंद्र गुप्ता

जवाबों:


175

आप एक सरणी का उपयोग कर सकते हैं और indexOf:

if ([1,3,12].indexOf(foo) > -1)

1
मैं यह पसंद है। यह भी संभव है कि मैं 'अनुमान' के माध्यम से प्रोटोटाइप के माध्यम से एक 'सम्‍मिलित' समारोह तैयार करूं, ताकि> -1 का उपयोग समाप्त हो सके।
19

1
@pimvdb: ध्यान दें कि आपको अपने स्वयं के कार्यान्वयन की आवश्यकता हो सकती indexOfहै जो केवल ECMAScript 5 वें संस्करण के बाद से उपलब्ध है।
गुमबो १bo

एक अन्य जवाब में यह वास्तव में उल्लेख किया गया है, मुझे नहीं पता था कि, धन्यवाद
pimvdb

क्या '>' किसी तरह 'से बेहतर है! =='
मैक्स वाटरमैन

117

ECMA2016 में आप शामिल विधि का उपयोग कर सकते हैं । यह मैंने देखा है सबसे साफ तरीका है। (IE (Polyfill लिंक में है) को छोड़कर सभी प्रमुख ब्राउज़रों द्वारा समर्थित

if([1,3,12].includes(foo)) {
    // ...
}

4
चर if([a,b,c].includes(foo))या तार के लिएif(['a','b','c'].includes(foo))
Hastig Zusammenstellen

चर => के लिए if([a,b,c].includes(foo))क्योंकि उद्धरण चिह्न इसे स्ट्रिंग बना देगा। @HastigZusammenstellen
iambinodstha

2
@BinodShrestha मुझे लगता है कि मैंने वही लिखा है, जब तक कि मुझे कुछ याद नहीं है। "चर के लिए .. या तार ..."
हैस्टिग ज़ुसमेनस्टेलन

16

प्रदान किए गए उत्तरों का उपयोग करते हुए, मैं निम्नलिखित के साथ समाप्त हुआ:

Object.prototype.in = function() {
    for(var i=0; i<arguments.length; i++)
       if(arguments[i] == this) return true;
    return false;
}

इसे इस तरह कहा जा सकता है:

if(foo.in(1, 3, 12)) {
    // ...
}

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

/foo|bar|something/.test(str);

अधिक सटीक होने के लिए, यह सटीक स्ट्रिंग की जांच करेगा, लेकिन फिर एक सरल समानता परीक्षण के लिए अधिक जटिल है:

/^(foo|bar|something)$/.test(str);

5
भगवान! मैं अचरज में हूं कि काम करता है - inजावास्क्रिप्ट में एक कीवर्ड है। उदाहरण के लिए, function in() {}; in()सिंटैक्स त्रुटि में परिणाम, कम से कम फ़ायरफ़ॉक्स में, और मुझे यकीन नहीं है कि आपका कोड क्यों नहीं है। :-)
बेन ब्लैंक

3
इसके अलावा, इसका अक्सर विस्तार करने के लिए बुरा अभ्यास माना जाता है Object.prototype, क्योंकि यह for (foo in bar)दुर्भाग्यपूर्ण तरीकों से प्रभावित होता है। शायद इसे function contains(obj) { for (var i = 1; i < arguments.length; i++) if (arguments[i] === obj) return true; return false; }एक तर्क के रूप में ऑब्जेक्ट को बदल दें और पास करें?
बेन ब्लैंक

आपकी प्रतिक्रिया के लिए धन्यवाद, और Google क्लोजर कंपाइलर भी संकलन करते समय एक त्रुटि देता है, जबकि यह कोड स्वयं सुंदर तरीके से काम करता है। वैसे भी, यह सुझाव दिया गया है कि एक सहायक वर्ग इस काम को बेहतर तरीके से कर सकता है Object.prototypeजैसा कि आप भी उल्लेख करते हैं। हालांकि, मैं इस तरह से पसंद करता हूं, क्योंकि चेक के लिए अंकन प्यारा है, बस foo.in(1, 2, "test", Infinity), पाई के रूप में आसान है।
pimvdb

और एक फ़ंक्शन in()को परिभाषित करना नियमित रूप से क्रोम पर भी विफल रहता है, लेकिन प्रोटोटाइप काम करता है ... :)
pimvdb

3
Object.prototype को विस्तारित करना एक विरोधी पैटर्न है और इसका उपयोग नहीं किया जाना चाहिए। इसके बजाय एक फ़ंक्शन का उपयोग करें।
वर्नोन

9

if(foo in L(10,20,30))यदि आप परिभाषित करते हैं कि आप लिख सकते Lहैं

var L = function()
{
    var obj = {};
    for(var i=0; i<arguments.length; i++)
        obj[arguments[i]] = null;

    return obj;
};

यह वास्तव में पूर्व के उत्तरों से भी अधिक स्पष्ट है, धन्यवाद!
पिमवेदब

2
मुझे लगता है कि यह टिप्पणी करना समझदारी है कि प्रोटोटाइप फ़ंक्शंस 'इन ए अरेंज / ऑब्जेक्ट' भी होते हैं - इसलिए अगर एरे / ऑब्जेक्ट के प्रोटोटाइप में कोई फंक्शन 'रिमूव' होता है, तो यह हमेशा सही रहेगा यदि आप कोड करते हैं 'remove' in L(1, 3, 12), हालांकि आपने नहीं किया था सूची में डालने के लिए 'निकालें' निर्दिष्ट करें।
पिमवेदब

7

यह आसानी से विस्तार योग्य और पठनीय है:

switch (foo) {
    case 1:
    case 3:
    case 12:
        // ...
        break

    case 4:
    case 5:
    case 6:
        // something else
        break
}

लेकिन जरूरी आसान नहीं :)


मैंने वास्तव में इस विधि का उपयोग किया था क्योंकि मैं प्रत्येक मूल्य के आगे एक टिप्पणी रखना चाहता था ताकि यह वर्णन किया जा सके कि इससे संबंधित मूल्य क्या है, इसे प्राप्त करने का सबसे पठनीय तरीका था।
फॉल्क्रॉफ्ट

@pholcroft यदि आपको यह वर्णन करने की आवश्यकता है कि प्रत्येक मूल्य आपके लिए क्या है, तो आपको एक एनम, या वर्ग बनाना चाहिए, और वर्णनात्मक नाम रखने के लिए अपने गुणों को लिखना चाहिए।
red_dorian

6
var a = [1,2,3];

if ( a.indexOf( 1 ) !== -1 ) { }

ध्यान दें कि indexOf कोर ECMAScript में नहीं है। आपको IE और संभवतः अन्य ब्राउज़रों के लिए एक स्निपेट की आवश्यकता होगी जो Array.prototype.indexOf का समर्थन नहीं करते हैं।

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(searchElement /*, fromIndex */)
  {
    "use strict";

    if (this === void 0 || this === null)
      throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;
    if (len === 0)
      return -1;

    var n = 0;
    if (arguments.length > 0)
    {
      n = Number(arguments[1]);
      if (n !== n)
        n = 0;
      else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0))
        n = (n > 0 || -1) * Math.floor(Math.abs(n));
    }

    if (n >= len)
      return -1;

    var k = n >= 0
          ? n
          : Math.max(len - Math.abs(n), 0);

    for (; k < len; k++)
    {
      if (k in t && t[k] === searchElement)
        return k;
    }
    return -1;
  };
}

यह सीधे मोजिला की नकल है। लिंक करने के लिए बहुत आलसी था। developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
मध्य-पूर्व

यदि आप वास्तव में बिट्स को स्थानांतरित नहीं कर रहे हैं तो क्या लेन-देन को परिभाषित करने का एक कारण है? क्या यहां कुछ निहित जबरदस्ती चल रही है?
jaredad7

3

इसके अलावा, जिन मूल्यों के खिलाफ आप परिणाम की जांच कर रहे हैं वे सभी अद्वितीय हैं आप सेट.प्रोटोटाइप.हास () का भी उपयोग कर सकते हैं ।

var valid = [1, 3, 12];
var goodFoo = 3;
var badFoo = 55;

// Test
console.log( new Set(valid).has(goodFoo) );
console.log( new Set(valid).has(badFoo) );


2

अब आपके पास इस परिदृश्य को हल करने के लिए एक बेहतर समाधान हो सकता है, लेकिन अन्य तरीका जो मैंने पसंद किया।

const arr = [1,3,12]
if( arr.includes(foo)) { // it will return true if you `foo` is one of array values else false
  // code here    
}

मैंने इंडेक्सऑफ चेक पर उपरोक्त समाधान को प्राथमिकता दी है, जहां आपको इंडेक्स की भी जांच करने की आवश्यकता है।

डॉक्स शामिल हैं

if ( arr.indexOf( foo ) !== -1 ) { }

1

मुझे स्वीकृत उत्तर पसंद आया, लेकिन सोचा कि एरियर लेने के साथ-साथ इसे सक्षम बनाना भी अच्छा होगा, इसलिए मैंने इसे इसके लिए विस्तारित किया:

Object.prototype.isin = function() {
    for(var i = arguments.length; i--;) {
        var a = arguments[i];
        if(a.constructor === Array) {
            for(var j = a.length; j--;)
                if(a[j] == this) return true;
        }
        else if(a == this) return true;
    }
    return false;
}

var lucky = 7,
    more = [7, 11, 42];
lucky.isin(2, 3, 5, 8, more) //true

आप बदलकर प्रकार बलात्कार को हटा सकते हैं ==करने के लिए ===


1

यदि आपके पास अंडरस्कोर तक पहुंच है, तो आप निम्नलिखित का उपयोग कर सकते हैं:

if (_.contains([1, 3, 12], foo)) {
  // ...
}

contains लोदाश में भी काम करते थे (V4 से पहले), अब आपको उपयोग करना है includes

if (_.includes([1, 3, 12], foo)) {
  handleYellowFruit();
}

1

यह एक छोटा सहायक बन्ध है:

const letters = ['A', 'B', 'C', 'D'];

function checkInList(arr, val) {
  return arr.some(arrVal => val === arrVal);
}

checkInList(letters, 'E');   // false
checkInList(letters, 'A');   // true

अधिक जानकारी यहाँ ...


बहुत अच्छा दृष्टिकोण: अपने विचार से शुरू करके आप इसे एक सहायक फंक के बिना भी कर सकते हैं:const valToCheck = 'E'; const check = ['A', 'B', 'C', 'D'].some(option => option === valToCheck); // false
जियोर्जियो टेंपेस्टा

लेकिन एक बार जब मैंने कोड प्राप्त करना शुरू कर दिया है, तो मुझे पता चला है कि includesबेहतर विकल्प बन गया है, जैसा कि @ एलिस्टर के जवाब में है:const valToCheck = 'E'; const check = ['A', 'B', 'C', 'D'].includes(valToCheck); // false
जियोर्जियो

0

मैंने इसे पूरा करने के लिए jQuery inArray फ़ंक्शन और मानों की एक सरणी का उपयोग किया :

myArr = ["A", "B", "C", "C-"];

var test = $.inArray("C", myArr)  
// returns index of 2 returns -1 if not in array

if(test >= 0) // true

-4

पश्चात के लिए आप विकल्प के रूप में नियमित अभिव्यक्ति का उपयोग करना चाह सकते हैं। काफ़ी अच्छा ब्राउज़र समर्थन में अच्छी तरह से (संदर्भ। Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#Browser_compatibility )

इसे इस्तेमाल करे

if (foo.toString().match(/^(1|3|12)$/)) {
    document.write('Regex me IN<br>');
} else {
    document.write('Regex me OUT<br>');
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.