यह निर्धारित करें कि स्ट्रिंग जावास्क्रिप्ट में सूची में है या नहीं


262

एसक्यूएल में हम देख सकते हैं कि क्या कोई स्ट्रिंग इस तरह सूची में है:

Column IN ('a', 'b', 'c')

जावास्क्रिप्ट में ऐसा करने का एक अच्छा तरीका क्या है? ऐसा करने के लिए यह बहुत भद्दी है:

if (expression1 || expression2 || str === 'a' || str === 'b' || str === 'c') {
   // do something
}

और मैं इसके प्रदर्शन या स्पष्टता के बारे में निश्चित नहीं हूं:

if (expression1 || expression2 || {a:1, b:1, c:1}[str]) {
   // do something
}

या कोई स्विच फ़ंक्शन का उपयोग कर सकता है:

var str = 'a',
   flag = false;

switch (str) {
   case 'a':
   case 'b':
   case 'c':
      flag = true;
   default:
}

if (expression1 || expression2 || flag) {
   // do something
}

लेकिन यह एक भयानक गड़बड़ है। कोई विचार?

इस मामले में, मुझे इंटरनेट एक्सप्लोरर 7 का उपयोग करना होगा क्योंकि यह कॉर्पोरेट इंट्रानेट पृष्ठ के लिए है। तो ['a', 'b', 'c'].indexOf(str) !== -1कुछ वाक्यविन्यास चीनी के बिना मूल रूप से काम नहीं करेगा।


1
क्या आप बता सकते हैं कि "स्ट्रिंग सूची में है" और "सरणी में ऑब्जेक्ट शामिल हैं" के बीच वास्तव में क्या अंतर है?
मिशाल पेरोलाकोव्स्की

2
@ गोथो क्योंकि एक सूची हमेशा एक सरणी नहीं होती है, और एक स्ट्रिंग एक वस्तु नहीं है? यह कैसे स्पष्ट हो सकता है?
एरिक

@EricE अगर यह वही है जो आपने नोट में उल्लेख किया है, तो यह प्रश्न बंद कर दिया जाना चाहिए और आगे कोई बाउंटी / उत्तर की अनुमति नहीं होनी चाहिए। पहले से ही पोस्ट किए गए उत्तर किसी की भी मदद लेने के लिए पर्याप्त हैं।
विकासदीप सिंह

@VicJordan शायद आप अपनी टिप्पणी हटाना चाहेंगे क्योंकि यह अब लागू नहीं होती है।
ErikE

जवाबों:


279

आप कॉल कर सकते हैं indexOf:

if (['a', 'b', 'c'].indexOf(str) >= 0) {
    //do something
}

15
एकमात्र समस्या Array.prototype.indexOfयह है कि यह IE पर काम नहीं करेगा, दुख की बात यह है कि IE8 में इस पद्धति का अभाव है।
CMS

2
लेकिन आप चाहें तो इसे परिभाषित कर सकते हैं। देखें soledadpenades.com/2007/05/17/arrayindexof-in-internet-explorer
जेसन हॉल

यहाँ "वास्तविक" माल हैं: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
ErikE

8
@ImJasonH: उस पेज पर कोड वास्तव में बहुत खराब है IMHO, उदाहरण के लिए, चेक जो Array.indexOfओवरराइड करने से पहले मौजूद है Array.prototype.indexOfजो एक ही चीज नहीं है। मैं मोज़िला द्वारा यहां उपलब्ध कार्यान्वयन की सिफारिश करूंगा: developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/…
CMS

1
@CMS, @Emtucifor को देखें, तो मोज़िला कार्यान्वयन बहुत बेहतर है।
जेसन हॉल

230

एक्मास्क्रिप्ट 6

यदि आप ES6 का उपयोग कर रहे हैं, तो आप आइटमों की एक सरणी का निर्माण कर सकते हैं, और उपयोग कर सकते हैं includes:

['a', 'b', 'c'].includes('b')

इसके कुछ अंतर्निहित लाभ हैं indexOfक्योंकि यह NaNसूची की उपस्थिति के लिए ठीक से परीक्षण कर सकता है , और लापता सरणी तत्वों जैसे कि बीच में [1, , 2]से एक से मिलान कर सकता है undefinedincludesभी काम करता है पर जावास्क्रिप्ट सरणियों टाइप किया जैसे Uint8Array

आप (जैसे आईई या एज के लिए के रूप में) ब्राउज़र समर्थन के बारे में चिंतित हैं, तो आप कर सकते हैं की जाँच Array.includesCanIUse.Com पर , और यदि आप जिसकी कमी है एक ब्राउज़र या ब्राउज़र संस्करण लक्षित करना चाहते हैं includes, मेरा सुझाव है polyfill.io polyfilling के लिए।

बिना किसी ऐरे के

आप isInListनिम्नानुसार एक नई संपत्ति जोड़ सकते हैं :

if (!String.prototype.isInList) {
   String.prototype.isInList = function() {
      let value = this.valueOf();
      for (let i = 0, l = arguments.length; i < l; i += 1) {
         if (arguments[i] === value) return true;
      }
      return false;
   }
}

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

'fox'.isInList('weasel', 'fox', 'stoat') // true
'fox'.isInList('weasel', 'stoat') // false

आप एक ही काम कर सकते हैं Number.prototype

Array.indexOf

यदि आप एक आधुनिक ब्राउज़र का उपयोग कर रहे हैं, तो indexOfहमेशा काम करता है। हालाँकि, IE8 और पहले के लिए आपको पॉलीफ़िल की आवश्यकता होगी।

यदि indexOfरिटर्न -1 है, तो आइटम सूची में नहीं है। हालांकि, ध्यान रखें कि यह विधि ठीक से जांच नहीं करेगी NaN, और जब यह स्पष्ट रूप से मेल खा सकती है undefined, तो यह अनुपलब्ध तत्व को undefinedसरणी में नहीं मिला सकती है [1, , 2]

के लिए indexOfया includesIE में Polyfill , या किसी अन्य ब्राउज़र / संस्करण का समर्थन नहीं है

यदि आप ऊपर बताए अनुसार पॉलिफिल.आईओ जैसी सेवा का उपयोग नहीं करना चाहते हैं , तो आप हमेशा अपने स्वयं के स्रोत कोड मानकों-अनुरूप कस्टम पॉलीफिल्स में शामिल कर सकते हैं। उदाहरण के लिए, मोज़िला डेवलपर नेटवर्क के लिए एक है indexOf

इस स्थिति में जहां मुझे इंटरनेट एक्सप्लोरर 7 के लिए एक समाधान करना था, मैंने "अपने स्वयं के" indexOf()फ़ंक्शन के सरल संस्करण को रोल किया, जो मानकों के अनुरूप नहीं है:

if (!Array.prototype.indexOf) {
   Array.prototype.indexOf = function(item) {
      var i = this.length;
      while (i--) {
         if (this[i] === item) return i;
      }
      return -1;
   }
}

हालाँकि, मुझे नहीं लगता कि Array.prototypeदीर्घकालिक में संशोधन सबसे अच्छा जवाब है। जावास्क्रिप्ट में संशोधन Objectऔर Arrayप्रोटोटाइप गंभीर बग पैदा कर सकते हैं। आपको यह तय करने की आवश्यकता है कि ऐसा करना आपके अपने परिवेश में सुरक्षित है या नहीं। प्राथमिक नोट में यह है कि एक सरणी (जब Array.prototype गुणों को जोड़ा गया है) को पुनरावृत्त करना एक for ... inकुंजी के रूप में नया फ़ंक्शन नाम लौटाएगा:

Array.prototype.blah = function() { console.log('blah'); };
let arr = [1, 2, 3];
for (let x in arr) { console.log(x); }
// Result:
0
1
2
blah // Extra member iterated over!

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

उस टूट-फूट से बचने का पुराना तरीका, गणना के दौरान, प्रत्येक मूल्य की जांच करना है कि क्या वस्तु वास्तव में उसके पास गैर-विरासत वाली संपत्ति के रूप में है if (arr.hasOwnProperty(x))और केवल उसके साथ काम करती है x

नई ES6 तरीका यह अतिरिक्त मुख्य समस्या से बचने के लिए उपयोग करने के लिए है ofके बजाय in, for (let x of arr)। हालाँकि, जब तक आप इस बात की गारंटी नहीं दे सकते कि आपके सभी कोड और थर्ड-पार्टी लाइब्रेरी सख्ती से इस पद्धति से चिपके रहते हैं, तब इस प्रश्न के प्रयोजनों के लिए आप संभवतः includesऊपर बताए अनुसार उपयोग करना चाहेंगे ।


2
यहाँ एक और अच्छी बात है polyfill के लिए indexOfMDN द्वारा प्रदान की। यह मूल रूप से एक ही काम करता है लेकिन आसान मूल्यांकन के लिए शॉर्ट सर्किट के एक जोड़े के साथ।
काइलमिट

1
Downvoter: कृपया टिप्पणी करें। इससे क्या समस्या है? यह फ़ंक्शन मानकों के अनुरूप नहीं है, और होने की कोशिश नहीं कर रहा है।
ErikE


@lmiguelmh कैसे "पॉलीफ़िल" के बारे में जिसे मैंने खुद मोज़िला डॉक्स से एक लिंक पोस्ट किया था? किसी भी मामले में, यह फ़ंक्शन इतना सरल है कि मैं वास्तव में परीक्षण के बारे में बहुत चिंतित नहीं हूं। और जो कोई भी है, उसे "पहले से ही परीक्षण किए गए" फ़ंक्शन को नहीं लेना चाहिए, लेकिन जो भी वे उपयोग करते हैं, खुद को परीक्षण करना चाहिए। इसलिए आपकी टिप्पणी थोड़ी गलत है। क्या आपने मेरे कार्य के साथ एक विशिष्ट दोष की पहचान की है?
एरिक

@ आप सही है कि यह फ़ंक्शन मर चुका है और आपके उत्तर का उपयोग करने वाले किसी व्यक्ति को इसका पता होना चाहिए। मैंने आपका लिंक पहली जगह में नहीं देखा क्योंकि मैं "उत्तर"
ढूंढ

53

अधिकांश उत्तर Array.prototype.indexOfविधि का सुझाव देते हैं , एकमात्र समस्या यह है कि यह IE9 से पहले किसी भी IE संस्करण पर काम नहीं करेगा ।

एक विकल्प के रूप में मैं आपको दो और विकल्प छोड़ता हूं जो सभी ब्राउज़रों पर काम करेंगे:

if (/Foo|Bar|Baz/.test(str)) {
  // ...
}


if (str.match("Foo|Bar|Baz")) {
  // ...
}

हम्म, यह उल्लेख करने के लिए धन्यवाद कि, सीएमएस। यह सिर्फ इतना होता है कि यह एक कॉर्पोरेट इंट्रानेट के लिए है और वे उपयोग करते हैं ... लगता है कि क्या ... IE। चूँकि नियमित अभिव्यक्ति विधि मुझे वसीयत देती है, इसलिए मुझे या तो एक ऐसा फंक्शन बनाना होगा, जो मेरे पोस्ट (तीसरे कोड ब्लॉक) में सुझाए गए ऑब्जेक्ट मेथड का उपयोग करे।
एरिक

13
यह मेल खाएगा "HiFooThere"- मैं /^(?:Foo|Bar|Baz)$/इसके बजाय (स्ट्रिंग की शुरुआत, गैर-कैप्चरिंग ग्रुप, स्ट्रिंग का अंत) के साथ जाऊंगा ।
TrueWill

indexOfअब IE 9 और MDN के अनुसार ऊपर समर्थित है ।
क्रॉक

28

एरे के पास एक indexOfविधि है जिसका उपयोग स्ट्रिंग्स की खोज के लिए किया जा सकता है:

js> a = ['foo', 'bar', 'baz']
foo,bar,baz
js> a.indexOf('bar')
1
js> a.indexOf('quux')
-1

3
यह पुराने ब्राउज़रों पर विफल हो जाएगा।
epascarello

ओह ... उल्लेख करते हुए कि यह IE में काम नहीं करता है अच्छा होता। :)
एरिक

2
@epascarello: न केवल पुराने ब्राउज़रों में, यह IE में किसी भी IE पर विफल होगा , यहां तक ​​कि IE8 में :(
CMS

12

मेरे द्वारा उपयोग की गई एक ट्रिक है

>>> ("something" in {"a string":"", "somthing":"", "another string":""})
false
>>> ("something" in {"a string":"", "something":"", "another string":""})
true

आप कुछ ऐसा कर सकते थे

>>> a = ["a string", "something", "another string"];
>>> b = {};
>>> for(var i=0; i<a.length;i++){b[a[i]]="";} /* Transform the array in a dict */
>>> ("something" in b)
true

वॉयेजर, "किसी भी तेज / धीमी / बेहतर / बेहतर" में उपयोग कर रहा है या आइटम को हटाने की कोशिश कर रहा है, जैसा कि मेरे प्रश्न में तीसरा कोड ब्लॉक है? इसके अलावा, यदि आप चीज के माध्यम से लूप करने जा रहे हैं, तो मुझे लगता है कि आप उस समय एलीमेंट में तत्व की जांच कर सकते हैं ... बस एक फंक्शन में लूप लपेटें। और जो इसके लायक var i=a.length;while (i--) {/*use a[i]*/}है वह सबसे तेज़ लूप विधि है (यदि रिवर्स ऑर्डर स्वीकार्य है)।
एरिक

@Emtucifor: यह वास्तव में आप क्या कर रहे हैं पर निर्भर करता है, और मुझे लगता है कि यह अलग-अलग जावास्क्रिप्ट इंजन पर अलग तरह से काम कर सकता है। यदि आपके डेटा को किसी भी बिंदु पर एक शब्दकोश के उपयोग की आवश्यकता होगी, तो इसे इस तरह से बनाना बेहतर है। मुझे लगता है कि एक बार तानाशाह द्वारा वस्तु बनाए जाने पर इंजन पर कार्यान्वयन विवरण (ऑब्जेक्ट के लिए हैश टेबल का उपयोग) के कारण यह तेजी से होगा ।
एस्टेबन कुबेर

जावास्क्रिप्ट में, इसे एक तानाशाह नहीं कहा जाता है, इसे एक वस्तु कहा जाता है
सोलोमन उको

8

ये मेरा:

String.prototype.inList=function(list){
    return (Array.apply(null, arguments).indexOf(this.toString()) != -1)
}

var x = 'abc';
if (x.inList('aaa','bbb','abc'))
    console.log('yes');
else
    console.log('no');

यदि आप किसी सरणी को पास कर रहे हैं, तो यह तेज़ है:

String.prototype.inList=function(list){
    return (list.indexOf(this.toString()) != -1)
}

var x = 'abc';
if (x.inList(['aaa','bbb','abc']))
    console.log('yes')

यहाँ है jsperf: http://jsperf.com/bmcgin-inlsit


सच कहूँ तो, जहाँ आप एक सरणी पास करते हैं वह शायद अधिक उपयोगी होगा, और यह संभवतः Arrayप्रोटोटाइप पर होना चाहिए : शायद कुछ ऐसा हो Array.prototype.contains
सोलोमन उको

6

RegExpसार्वभौमिक है, लेकिन मैं समझता हूं कि आप सरणियों के साथ काम कर रहे हैं। तो, इस दृष्टिकोण की जाँच करें। मैं इसका उपयोग करने के लिए उपयोग करता हूं, और यह बहुत प्रभावी और तेजी से धधक रहा है!

var str = 'some string with a';
var list = ['a', 'b', 'c'];
var rx = new RegExp(list.join('|'));

rx.test(str);

आप कुछ संशोधन भी लागू कर सकते हैं, अर्थात:

एक लाइन

new RegExp(list.join('|')).test(str);

असंवेदनशील मामला

var rx = new RegExp(list.join('|').concat('/i'));


और बहुत सारे!


रेगेक्स का उपयोग करने के लिए विशेष वर्णों के एक समूह से बचने की आवश्यकता होती है। यह भी कम स्पष्ट है। मुझे नहीं लगता कि यह एक अच्छा समाधान है।
एरिक

@ErikE मैं आपके आरक्षण को समझता हूं इसलिए मैंने अपना जवाब एक और कोड जोड़कर अपडेट किया है जो RegExp का उपयोग नहीं करता है, यह IE के साथ अप्रचलित है, बहुत ही मुहावरेदार और तेज़ है।
सोसपेडरा

आपका अतिरिक्त कोड मेरे उत्तर का एक डुप्लिकेट है, जिसे मैंने 5 साल पहले प्रदान किया था, जब आप रेगेक्स समाधान पोस्ट करने का फैसला किया था। भाग लेने के लिए धन्यवाद, और साथ ही मुझे लगता है कि आपके पूर्व उत्तर में वापस आना सबसे अच्छा है।
एरिक

@ एरिक हाँ, तुम सही हो, मैं सवाल में जवाब के लिए जाँच करने के लिए उपयोग नहीं करते। और मैं मानता हूं कि यह वास्तव में समान है।
सोसपेडरा

6

IndexOf का उपयोग करना (यह IE8 के साथ काम नहीं करता है)।

if (['apple', 'cherry', 'orange', 'banana'].indexOf(value) >= 0) {
    // found
}

IE8 का समर्थन करने के लिए, आप मोज़िला के इंडेक्सऑफ़ को लागू कर सकते हैं।

if (!Array.prototype.indexOf) {
    // indexOf polyfill code here
}

String.prototype.match (डॉक्स) के माध्यम से नियमित अभिव्यक्तियाँ।

if (fruit.match(/^(banana|lemon|mango|pineapple)$/)) {

}

1
क्या आप देखते हैं कि आप पृष्ठ के अन्य उत्तरों की नकल कर रहे हैं? यह कोई मूल्य नहीं जोड़ता है।
एरिक

5

लगता है कि आपको in_array फ़ंक्शन का उपयोग करने की आवश्यकता है।

jQuery -> inArray

प्रोटोटाइप -> Array.indexOf

या, ये उदाहरण देखें कि क्या आप jQuery या प्रोटोटाइप का उपयोग नहीं कर रहे हैं:

स्टाइलिस्टिक नोट: वेरिएबल्स ने इस चीज़ का नामकरण किया, जिसका नाम आपको इस बारे में बताने के लिए होना चाहिए कि उनमें क्या है (संज्ञा)।


ओह, वे चर नहीं थे, लेकिन अभिव्यक्ति के लिए यादृच्छिक प्लेसहोल्डर के रूप में थे ... बस इस बात का एक उदाहरण कि मैंने स्क्रिप्ट का उपयोग करने की योजना कैसे बनाई।
एरिक

5

indexOfप्रोटोटाइप के Enumerable.include () का उपयोग करके (जो अन्य पोस्टरों ने सुझाव दिया है) इसके अलावा , इसे और अधिक साफ और संक्षिप्त बना सकते हैं:

var list = ['a', 'b', 'c'];
if (list.include(str)) {
  // do stuff
}

5
Enumerable.include () पदावनत कर दिया गया है, लेकिन Array.prototype.includes () आ रहा है, और पहले से ही IE (बेशक) और एज (बेशक) को छोड़कर ज्यादातर ब्राउज़रों में काम कर रहा है।
व्हाइटबर्ड

2

सवाल के लिए धन्यवाद, और Array.indexOf विधि का उपयोग कर समाधान।

मैंने इस समाधान से कोड का उपयोग एक इनलिस्ट () फंक्शन बनाने के लिए किया, जो IMO, लेखन को सरल और पढ़ने में स्पष्ट करेगा:

function inList(psString, psList) 
{
    var laList = psList.split(',');

    var i = laList.length;
    while (i--) {
        if (laList[i] === psString) return true;
    }
    return false;
}

उपयोग:

if (inList('Houston', 'LA,New York,Houston') {
  // THEN do something when your string is in the list
}

1
जावास्क्रिप्ट एरे लिटरल्स बहुत आसान हैं, मुझे नहीं लगता कि जब आप कर सकते हैं तो आप क्यों विभाजित होंगे 'Houston'.inList(['LA', 'New York', 'Houston'])। शायद if (!String.prototype.inList) {String.prototype.inList = function(arr) {return arr.indexOf(this) >= 0};}या अपनी whileविधि का उपयोग कर ।
EricE

0

मुझे आश्चर्य है कि किसी ने एक साधारण फ़ंक्शन का उल्लेख नहीं किया था जो एक स्ट्रिंग और एक सूची लेता है।

function in_list(needle, hay)
{
    var i, len;

    for (i = 0, len = hay.length; i < len; i++)
    {
        if (hay[i] == needle) { return true; }
    }

    return false;
}

var alist = ["test"];

console.log(in_list("test", alist));

जिम ने ठीक वही किया जो आप सुझाते हैं , सैम, 27 अगस्त को 1:29 बजे। वास्तव में, मेरी चयनित उत्तर, एक ही बात काफी है बस के साथ स्ट्रिंग की आपूर्ति इस बल्कि एक पैरामीटर से।
एरिक

@ErikE क्षमा करें, जैसा कि आपने कहा, जिम्स का जवाब मुझे अजीब लगा। और आपका स्वीकृत जवाब एक रिटर्न देता है int, जहां कुछ लोग इस सवाल के जवाब में आ सकते boolहैं। लगा कि यह कुछ लोगों की मदद कर सकता है।
सैमुअल पार्किंसन

0

मेरा समाधान इस तरह एक वाक्यविन्यास में परिणाम:

// Checking to see if var 'column' is in array ['a', 'b', 'c']

if (column.isAmong(['a', 'b', 'c']) {
  // Do something
}

और मैं इसे इस तरह से मूल वस्तु प्रोटोटाइप का विस्तार करके लागू करता हूं:

Object.prototype.isAmong = function (MyArray){
   for (var a=0; a<MyArray.length; a++) {
      if (this === MyArray[a]) { 
          return true;
      }
   }
   return false;
}

हम वैकल्पिक रूप से विधि को नाम दे सकते हैं IArray (लेकिन शायद InArray में नहीं) या बस isIn है।

लाभ: सरल, सीधा और स्व-दस्तावेजीकरण।


ऑब्जेक्ट एक्सटेंड करने में परेशानी हो सकती है। bolinfest.com/javascript/inheritance.php "Google मानचित्र टीम ने इसे कठिन तरीका सीखा" और ब्राउज़र कार्यान्वयन या अन्य उपयोगकर्ता कोड के साथ असंगति। मुझे अभी भी लगता है कि एरिक का जवाब सबसे अच्छा है क्योंकि एक सरणी पर पुनरावृत्ति करना एक हैशमैप में कुंजी ढूंढने की तुलना में धीमी है एक बार myValues[key];हैशमैप बनाया जाता है: जहां myValues ​​एक ऑब्जेक्ट है और कुंजी किसी भी स्ट्रिंग या संख्या है।
एचएमआर

-1

SLaks के उत्तर का एक सरलीकृत संस्करण भी काम करता है:

if ('abcdefghij'.indexOf(str) >= 0) {
    // Do something
}

.... चूँकि तार स्वयं सरणियों के प्रकार होते हैं। :)

यदि आवश्यक हो, तो इंटरनेट एक्सप्लोरर के लिए इंडेक्सऑफ़ फ़ंक्शन को लागू करें जैसा कि मेरे सामने वर्णित है।


1
यह केवल एकल-अक्षर स्ट्रिंग्स के साथ काम करेगा, जिसका इरादा नहीं था।
एरिक सेप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.