यदि कोई सरणी में जावास्क्रिप्ट शामिल है, तो मैं कैसे जांच सकता हूं?


3994

एक जावास्क्रिप्ट सरणी में एक मान होता है या नहीं, यह जानने के लिए सबसे संक्षिप्त और कुशल तरीका क्या है?

यह एकमात्र तरीका है जो मैं इसे करना जानता हूं:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

क्या इसे पूरा करने के लिए एक बेहतर और अधिक संक्षिप्त तरीका है?

यह स्टैक ओवरफ्लो प्रश्न से बहुत निकट से संबंधित है एक जावास्क्रिप्ट ऐरे में एक आइटम खोजने का सबसे अच्छा तरीका है? जो एक सरणी में वस्तुओं को खोजने का उपयोग करके संबोधित करता है indexOf


49
अभी-अभी परीक्षण किया गया है: आपका रास्ता वास्तव में ब्राउज़रों के लिए सबसे तेज़ है: jsperf.com/find-element-in-obj-vs-array/2 (इसके अलावा एक चर में पूर्व-बचत। इससे) indexOf का उपयोग करते हुए ($ में) .inArray) बहुत धीमा है
Jörn Berkefeld

17
कई लोगों ने उत्तर दिया है कि यहाँ Array # indexOf आपकी सबसे अच्छी पसंद है। लेकिन अगर आप कुछ ऐसा चाहते हैं जो बूलियन को सही तरीके से डाला जा सके, तो इसका उपयोग करें: ~[1,2,3].indexOf(4)0 वापस आ जाएगा जो कि असत्य के रूप में मूल्यांकन करेगा, जबकि ~[1,2,3].indexOf(3)-3 वापस आएगा जो कि सच के रूप में मूल्यांकन करेगा।
लॉर्डव्लड

8
~यह नहीं है कि आप एक बूलियन में बदलने के लिए क्या उपयोग करना चाहते हैं, इसके लिए आपको आवश्यकता है !। लेकिन इस मामले में आप -1 के साथ समानता की जांच करना चाहते हैं, इसलिए फ़ंक्शन समाप्त हो सकता return [1,2,3].indexOf(3) === -1; ~है एक बाइनरी नहीं है, यह व्यक्तिगत रूप से मूल्य के प्रत्येक बिट को पलटना होगा।
mcfedr

14
@Iordvlad [1,2,3].indexOf(4)वास्तव में -1 लौटेगा । के रूप में @mcfedr ने कहा, ~है बिटवाइज़-नहीं ऑपरेटर , ES5 11.4.8 देखते हैं। बात यह है कि, -1केवल 1 के बाइनरी प्रतिनिधित्व के बाद से , यह पूरक है 0, जो गलत के रूप में मूल्यांकन करता है। किसी अन्य संख्या का पूरक गैर-शून्य होगा, इसलिए यह सच है। तो, ~ठीक काम करता है और अक्सर के साथ संयोजन के रूप में प्रयोग किया जाता है indexOf
mnenecht

5
शीर्षक भ्रामक है। कहाँ है [[1,2],[3,4]].includes([3,4])?
mplungjan

जवाबों:


4373

आधुनिक ब्राउज़रों के पास है Array#includes, जो वास्तव में ऐसा करता है और IE को छोड़कर सभी द्वारा व्यापक रूप से समर्थित है:

console.log(['joe', 'jane', 'mary'].includes('jane')); //true

आप उपयोग भी कर सकते हैं Array#indexOf, जो कम प्रत्यक्ष है, लेकिन पुराने ब्राउज़रों के लिए पॉलीफिल की आवश्यकता नहीं है।


कई चौखटे भी इसी तरह के तरीके पेश करते हैं:

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


42
MooTools में Array.contains भी है जो एक बूलियन देता है, जो यहां वास्तविक प्रश्न की तरह लगता है।
रयान फ्लोरेंस

22
प्रोटोटाइप भी है Array.includeकि एक बूलियन देता है
user102008 22

46
यदि आप एक अच्छा ब्राउज़र का उपयोग कर रहे हैं, तो आप बस उपयोग कर सकते हैंarray.indexOf(object) != -1
सैम सोफ़्स

13
इसके अलावा, एक शर्त के रूप में अकेले indexOf का उपयोग न करें, क्योंकि पहला तत्व 0 वापस आ जाएगा और नकली के रूप में मूल्यांकन किया जाएगा
प्लस-

241
inArrayएक फ़ंक्शन के लिए एक भयानक नाम है जो तत्व के सूचकांक को लौटाता है, और -1यदि यह मौजूद नहीं है। मैं एक बूलियन को वापस करने की उम्मीद करूंगा।
टिम

433

2019 से अपडेट: यह उत्तर 2008 (11 वर्ष पुराना है) से है और आधुनिक जेएस उपयोग के लिए प्रासंगिक नहीं है। वादा किया गया प्रदर्शन सुधार उस समय के ब्राउज़रों में किए गए बेंचमार्क पर आधारित था। यह आधुनिक जेएस निष्पादन संदर्भों के लिए प्रासंगिक नहीं हो सकता है। यदि आपको एक आसान समाधान की आवश्यकता है, तो अन्य उत्तरों की तलाश करें। यदि आपको प्रासंगिक निष्पादन वातावरण में अपने लिए सर्वश्रेष्ठ प्रदर्शन, बेंचमार्क चाहिए।

जैसा कि दूसरों ने कहा है, सरणी के माध्यम से पुनरावृत्ति संभवतः सबसे अच्छा तरीका है, लेकिन यह साबित हो गया है कि whileजावास्क्रिप्ट में पुनरावृति करने के लिए एक घटता लूप सबसे तेज़ तरीका है। तो आप निम्नानुसार अपने कोड को फिर से लिखना चाहते हैं:

function contains(a, obj) {
    var i = a.length;
    while (i--) {
       if (a[i] === obj) {
           return true;
       }
    }
    return false;
}

बेशक, आप ऐरे प्रोटोटाइप का विस्तार कर सकते हैं:

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
}

और अब आप बस निम्नलिखित का उपयोग कर सकते हैं:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false

24
लेकिन सावधान रहें: stackoverflow.com/questions/237104/javascript-array-containsobj/…
MatrixFrog

22
"सिद्ध" एक मजबूत शब्द है। जेएस इंजन लगातार सुधार करते हैं, और 3 साल पहले मापा गया निष्पादन समय बहुत पुराना है।
orip

2
@ डमीर - मैं सहमत हूँ। यदि उपलब्ध हो तो इंडेक्सऑफ का उपयोग करने के लिए नमूना बदल दें, बस इसलिए लोग इस कोड को नेत्रहीन रूप से कॉपी-पेस्ट कर सकते हैं उन्हें सबसे अच्छा प्रदर्शन मिलेगा।
orip

1
@ cbmeeks हाँ, देखभाल निश्चित रूप से आवश्यक है। यह संभवत: ऐसा करने का मामला था, for (o in array)जो आम तौर पर सरणी के माध्यम से लूप करने पर नहीं किया जाना चाहिए ...
दामिर ज़ेकिअक्ट

1
ऐसा करने का सबसे अच्छा तरीका यह है कि अगर [1, 2, 3] .indexOf (1)> -1
डेविन जी रोड

206

indexOf हो सकता है, लेकिन यह "ECMA-262 मानक के लिए जावास्क्रिप्ट विस्तार है; जैसा कि यह मानक के अन्य कार्यान्वयन में मौजूद नहीं हो सकता है।"

उदाहरण:

[1, 2, 3].indexOf(1) => 0
["foo", "bar", "baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1

AFAICS Microsoft इसके लिए किसी प्रकार का विकल्प प्रदान नहीं करता है , लेकिन indexOfअगर आप चाहते हैं, तो इंटरनेट एक्सप्लोरर (और अन्य ब्राउज़र जो समर्थन नहीं करते हैं ) में समान कार्यक्षमता जोड़ सकते हैं , जैसे कि एक त्वरित Google खोज से पता चलता है (उदाहरण के लिए, यह एक) )।


वास्तव में, ब्राउज़रों के लिए इंडेक्सऑफ एक्सटेंशन के कार्यान्वयन का एक उदाहरण है जो आपके द्वारा लिंक किए गए developer.mozilla.org पेज पर इसका समर्थन नहीं करता है।
लॉयड कॉट

वास्तव में, यदि आप ब्राउज़रों के लिए ऐरे के प्रोटोटाइप में इंडेक्सोफ़ जोड़ते हैं जो इसका समर्थन नहीं करते हैं (यानी IE7) तो वे ऐरे में आइटम के माध्यम से लूप करते समय भी इस फ़ंक्शन पर लूप करने का प्रयास करेंगे। बुरा।
CpILL


क्या यह वस्तु की जांच के लिए लागू है। मुझे नहीं लगता कि यह वस्तु के मामले में काम करता है
हिमेश अढेसरा

168

ECMAScript 7 का परिचय Array.prototype.includes

इसका उपयोग इस तरह किया जा सकता है:

[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false

यह एक वैकल्पिक दूसरा तर्क भी स्वीकार करता है fromIndex:

[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true

इसके विपरीत indexOf, जो Strict Equality Comparison का उपयोग करता है , SameValueZero समानता एल्गोरिथम includesका उपयोग करके तुलना करता है। इसका मतलब है कि आप पता लगा सकते हैं कि किसी सरणी में कोई शामिल है :NaN

[1, 2, NaN].includes(NaN); // true

इसके विपरीत indexOf, includesगायब सूचकांकों को नहीं छोड़ता है:

new Array(5).includes(undefined); // true

वर्तमान में यह अभी भी एक मसौदा है, लेकिन इसे सभी ब्राउज़रों पर काम करने के लिए पॉलीफ़िल किया जा सकता है।


3
आईई और माइक्रोसॉफ़्ट एज (2015) ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) के लिए समर्थित नहीं
Adriano Resende

1
इसके अलावा प्रासंगिक, ES7 संगतता तालिका (जैसा दिखता है क्रोम अब इसका समर्थन करता है)
स्टाइल

क्या यह वस्तु की जांच के लिए लागू है। मुझे नहीं लगता कि यह वस्तु के मामले में काम करता है
हिमेश अढेसरा

128

शीर्ष उत्तर आदिम प्रकार मानते हैं लेकिन अगर आप यह जानना चाहते हैं कि किसी सरणी में किसी विशेषता के साथ कोई वस्तु है , तो Array.prototyp.some () एक बहुत ही सुंदर समाधान है:

const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]

items.some(item => item.a === '3')  // returns true
items.some(item => item.a === '4')  // returns false

इसके बारे में अच्छी बात यह है कि तत्व को मिल जाने के बाद पुनरावृत्ति को रोक दिया जाता है इसलिए अनावश्यक चलना चक्रों को बख्शा जाता है।

इसके अलावा, यह एक ifबयान में अच्छी तरह से फिट बैठता है क्योंकि यह एक बूलियन देता है:

if (items.some(item => item.a === '3')) {
  // do something
}

* जैसा कि टिप्पणी में बताया गया है, इस उत्तर के समय, सितंबर 2018, Array.prototype.some()पूरी तरह से समर्थित है: caniuse.com समर्थन तालिका


1
आज के रूप में, सितंबर 2018, Array.prototyp.some () पूरी तरह से समर्थित है: caniuse.com समर्थन तालिका
जाम

1
NWS में काम करना = = 8.10 के लिए AWS Node.js लैंबडा, इसलिए यह बहुत अच्छा है। बहुत साफ और सरल उपाय! 👍🏻
जॉर्डन

1
@ जैमेस यह अच्छी तरह से समर्थित हो सकता है, लेकिन याद रखें कि Arrow functionsइस उदाहरण में इतनी अच्छी तरह से समर्थित नहीं हैं। अधिक जानकारी के लिए यहाँ देखें: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
कामिल विटकोव्स्की

कुछ शॉर्ट-सर्किट करता है? या क्या यह पूरे सरणी को पुनरावृत्त करता है, भले ही इसका मूल्य मिल जाए?
डगलस गास्केल

@DouglasGaskell एक बार पाए जाने वाले पुनरावृत्ति को रोक देता है (उत्तर में वर्णित)
माइकल

112

मान लीजिए कि आपने एक सरणी परिभाषित की है जैसे:

const array = [1, 2, 3, 4]

नीचे जाँचने के तीन तरीके हैं कि क्या वहाँ है 3। उनमें से सभी trueया तो वापस आ जाते हैं false

मूल सरणी विधि (ES2016 के बाद से) ( संगतता तालिका )

array.includes(3) // true

कस्टम सरणी विधि के रूप में (पूर्व ES2016)

// Prefixing the method with '_' to avoid name clashes
Object.defineProperty(Array.prototype, '_includes', { value: function (v) { return this.indexOf(v) !== -1 }})
array._includes(3) // true

साधारण कार्य

const includes = (a, v) => a.indexOf(v) !== -1
includes(array, 3) // true

यह सही है अगर "b" एरे "a" में है ... मुझे नहीं पता कि इसे कैसे समझा जाए ...
william malo

4
यह हिस्सा मुझे समझ में नहीं आया "!! ~"। और मुझे लगता है कि यह IE8 में काम नहीं करेगा क्योंकि IE8 Array ऑब्जेक्ट पर indexOf () का समर्थन नहीं करता है।
svlada

62
"~" एक ऑपरेटर है जो एक संख्या से फर्श, अकशेरुकी और घटाव 1 करता है। indexOf रिटर्न -1 अगर यह विफल रहता है, तो "~" -1 को "0" में बदल देता है। "!!" बोलियों में संख्या बदल जाती है (!! 0 === झूठी)
विलियम मालो

1
शांत, लेकिन गंभीरता के लिए गंभीरता से y न केवल a.indexOf (b)> - 1,>> -1 -1 ".length ===" !! ~ ~ .length
सुपर

2
मैं बूलियन ऑपरेटरों के प्रभाव के बारे में ज्ञान की कमी को लाभहीन कहूंगा। लेकिन मैं पठनीय कोड के मूल्य के बारे में सहमत हूं, मैं निश्चित रूप से स्पष्ट रूप से लेबल किए गए फ़ंक्शन में इसे लपेटूंगा। और यही जेएस फ्रेमवर्क सबसे प्रमुख है।
okdewit

79

यहाँ एक जावास्क्रिप्ट 1.6 संगत कार्यान्वयन है Array.indexOf:

if (!Array.indexOf) {
    Array.indexOf = [].indexOf ?
        function(arr, obj, from) {
            return arr.indexOf(obj, from);
        } :
        function(arr, obj, from) { // (for IE6)
            var l = arr.length,
                i = from ? parseInt((1 * from) + (from < 0 ? l : 0), 10) : 0;
            i = i < 0 ? 0 : i;
            for (; i < l; i++) {
                if (i in arr && arr[i] === obj) {
                    return i;
                }
            }
            return -1;
        };
}

यह बहुत अच्छा लग रहा है, लेकिन थोड़ा भ्रमित: * लाइनों 1 और 3 के समकक्ष परीक्षण नहीं हैं? * प्रोटोटाइप का परीक्षण करना बेहतर नहीं होगा, और यदि आवश्यक हो तो फ़ंक्शन को Array.prototype में जोड़ना बेहतर होगा?
एवी फ्लैक्स

10
वे समान नहीं हैं। [].indexOfके लिए एक आशुलिपि है Array.prototype.indexOf। हमारे रक्षात्मक रक्षात्मक जावास्क्रिप्ट प्रोग्रामर हर कीमत पर मूल प्रोटोटाइप का विस्तार करने से बचते हैं।
मेर gsrlygsson

1
[].indexOfएक नया सरणी नहीं बना रहा है और फिर एक्सेस कर रहा है indexOf, जबकि Array.prototype.indexOfकेवल प्रोटोटाइप को सीधे एक्सेस करता है?
एलेक्स

3
@alex हाँ [].indexOf === Array.prototype.indexOf( फायरबग में इसे आज़माएं), लेकिन इसके विपरीत [].indexOf !== Array.indexOf
मेर gsrlygsson

57

उपयोग:

function isInArray(array, search)
{
    return array.indexOf(search) >= 0;
}

// Usage
if(isInArray(my_array, "my_value"))
{
    //...
}

25
x ? true : falseआमतौर पर बेमानी है। यह यहां पर है।
Ry-

@ मिनिटेक क्यों कहते हैं कि यह बेमानी है?
मतिस कानेपा

8
array.indexOf(search) >= 0पहले से ही एक बूलियन है। बस return array.indexOf(search) >= 0
Ry-

@minitech अच्छी तरह से धन्यवाद! वास्तव में मुझे नहीं पता था कि इस तरह के निर्माण को वापस किया जा सकता है। TIL कुछ नया।
मत्तीस कैनेपा

वास्तव में जावास्क्रिप्ट में किसी भी निर्माण को वापस किया जा सकता है
BT

49

जावास्क्रिप्ट Arrayऑब्जेक्ट का विस्तार करना वास्तव में एक बुरा विचार है क्योंकि आप नए गुणों (आपके कस्टम तरीकों) को for-inलूप में पेश करते हैं जो मौजूदा स्क्रिप्ट को तोड़ सकते हैं। कुछ साल पहले प्रोटोटाइप लाइब्रेरी के लेखकों को इस तरह की चीज़ को हटाने के लिए अपने पुस्तकालय कार्यान्वयन को फिर से इंजीनियर करना पड़ा था।

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


22
मैं असहमत हूं। लूप में फॉर-फॉर का उपयोग इस कारण से ठीक से सरणियों के लिए नहीं किया जाना चाहिए। लोकप्रिय जेएस पुस्तकालयों में से एक का उपयोग करते समय फॉप-इन लूप का उपयोग टूट जाएगा
टॉमस

क्या इसे बन्दर का पेटिंग माना जाएगा? lol कुछ लोग इसे पसंद करते हैं।
cbmeeks

33

एक लाइन:

function contains(arr, x) {
    return arr.filter(function(elem) { return elem == x }).length > 0;
}

8
array.filter(e=>e==x).length > 0के बराबर है, array.some(e=>e==x)लेकिन someअधिक कुशल है
अपोलो

32

एक सेकंड के लिए बॉक्स से बाहर निकलते हुए, यदि आप कई बार यह कॉल कर रहे हैं, तो हैश फंक्शन का उपयोग करके लुकअप करने के लिए मैप को एसोसिएटिव ऐरे का उपयोग करना बहुत अधिक कुशल है ।

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map


हालांकि यह स्पष्ट रूप से कई लोगों के लिए उपयोगी है, यह बेहतर होता अगर एक कोड स्निपेट जोड़ा जाता।
पाई 'ओह' पाह

28

मैं निम्नलिखित का उपयोग करता हूं:

Array.prototype.contains = function (v) {
    return this.indexOf(v) > -1;
}

var a = [ 'foo', 'bar' ];

a.contains('foo'); // true
a.contains('fox'); // false

24
function contains(a, obj) {
    return a.some(function(element){return element == obj;})
}

5 वें संस्करण में ECMA-262 मानक में Array.prototyp.some () जोड़ा गया था


अगर es6 का उपयोग करने से यह कैम के रूप में छोटा हो सकता हैcontains = (a, obj) => a.some((element) => element === obj))
diEcho

यहां तक कि IE9 के लिए समर्थन हासिल है () Array.prototype.some के रूप में ECMAScript 5
सनकैट २२

19

एक उम्मीद से तेज बोली-प्रक्रिया indexOf/ lastIndexOfविकल्प

2015

जबकि नई विधि में शामिल बहुत अच्छा है, समर्थन मूल रूप से अभी के लिए शून्य है।

यह लंबे समय से है कि मैं धीमी indexOf / lastIndexOf फ़ंक्शन को बदलने का तरीका सोच रहा था।

शीर्ष उत्तर को देखते हुए, एक प्रदर्शनकारी तरीका पहले ही मिल गया है। उन लोगों से मैंने contains@Damir Zekic द्वारा पोस्ट किया गया फंक्शन चुना जो सबसे तेज़ होना चाहिए। लेकिन यह भी कहा गया है कि बेंचमार्क 2008 से हैं और इसलिए पुराने हैं।

मैं भी पसंद करते हैं whileअधिक forहै, लेकिन नहीं एक विशिष्ट कारण के लिए मैं पाश के लिए एक साथ समारोह लेखन समाप्त। यह भी एक के साथ किया जा सकता है while --

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

जब आप जानते हैं कि आपने किसी सरणी को केवल मान के साथ धकेला है, तो lastIndexOf का उपयोग करना संभवतः सबसे अच्छा समाधान है, लेकिन यदि आपको बड़ी सरणियों के माध्यम से यात्रा करना है और परिणाम हर जगह हो सकता है, तो यह चीजों को तेज करने का एक ठोस समाधान हो सकता है।

द्विदिश indexOf / lastIndexOf

function bidirectionalIndexOf(a, b, c, d, e){
  for(c=a.length,d=c*1; c--; ){
    if(a[c]==b) return c; //or this[c]===b
    if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
  }
  return -1
}

//Usage
bidirectionalIndexOf(array,'value');

प्रदर्शन का परीक्षण

http://jsperf.com/bidirectionalindexof

परीक्षण के रूप में मैंने 100k प्रविष्टियों के साथ एक सरणी बनाई।

तीन प्रश्न: शुरुआत में, मध्य में और सरणी के अंत में।

मुझे उम्मीद है कि आपको यह दिलचस्प भी लगेगा और प्रदर्शन का परीक्षण करेगा।

नोट: जैसा कि आप देख सकते हैं कि मैंने containsindexOf और lastIndexOf आउटपुट को प्रतिबिंबित करने के लिए फ़ंक्शन को थोड़ा संशोधित किया है (इसलिए मूल रूप trueसे indexऔर इसके falseसाथ -1)। इससे उसे कोई नुकसान नहीं होना चाहिए।

सरणी प्रोटोटाइप संस्करण

Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
  for(c=this.length,d=c*1; c--; ){
    if(this[c]==b) return c; //or this[c]===b
    if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
  }
  return -1
},writable:false, enumerable:false});

// Usage
array.bidirectionalIndexOf('value');

फ़ंक्शन को सही या गलत या यहां तक ​​कि ऑब्जेक्ट, स्ट्रिंग या जो कुछ भी है उसे वापस करने के लिए आसानी से संशोधित किया जा सकता है।

और यहाँ whileसंस्करण है:

function bidirectionalIndexOf(a, b, c, d){
  c=a.length; d=c-1;
  while(c--){
    if(b===a[c]) return c;
    if(b===a[d-c]) return d-c;
  }
  return c
}

// Usage
bidirectionalIndexOf(array,'value');

यह कैसे हो सकता है?

मुझे लगता है कि एक सरणी में परिलक्षित सूचकांक प्राप्त करने के लिए सरल गणना इतनी सरल है कि यह वास्तविक लूप पुनरावृत्ति करने की तुलना में दो गुना तेज है।

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

http://jsperf.com/bidirectionalindexof/2


18

प्रदर्शन

आज 2020.01.07 मैं 15 चुने हुए समाधानों के लिए Chrome v78.0.0, Safari v13.0.4 और Firefox v71.0.0 पर MacOs HighSierra 10.13.6 पर परीक्षण करता हूं। निष्कर्ष

  • के आधार पर समाधान JSON, Setऔर आश्चर्यजनक रूप से find(के, एन, ओ) सभी ब्राउज़रों पर सबसे धीमे हैं
  • es6 includes(F) केवल क्रोम पर तेज है
  • for(सी, डी) और indexOf(जी, एच) पर आधारित समाधान छोटे और बड़े सरणियों पर सभी ब्राउज़रों पर काफी तेज हैं, इसलिए शायद वे कुशल समाधान के लिए सबसे अच्छा विकल्प हैं
  • समाधान जहां लूप के दौरान इंडेक्स घटता है, (B) संभवतः धीमा होता है क्योंकि CPU कैश का तरीका काम करता है
  • मैं बड़े सरणी के लिए परीक्षण भी चलाता हूं जब खोजा गया तत्व 66% लंबाई की स्थिति पर था, और for(C, D, E) के आधार पर समाधान समान परिणाम देता है (~ 630 ops / sec - लेकिन सफारी और फ़ायरफ़ॉक्स पर ई 10- था C और D से 20% धीमा)

परिणाम

यहां छवि विवरण दर्ज करें

विवरण

मैं 2 परीक्षण मामलों का प्रदर्शन करता हूं: 10 तत्वों वाले सरणी के लिए, और 1 सैन्य तत्व वाले सरणी। दोनों ही मामलों में हमने एरे के मध्य में खोजा गया तत्व रखा है।

ऐरे छोटे - 10 तत्व

आप अपनी मशीन में परीक्षण यहाँ कर सकते हैं

यहां छवि विवरण दर्ज करें

ऐरे बड़े - 1.000.000 तत्व

आप अपनी मशीन में परीक्षण यहाँ कर सकते हैं

यहां छवि विवरण दर्ज करें


16

यदि आप JavaScript 1.6 या बाद के (Firefox 1.5 या बाद के) का उपयोग कर रहे हैं, तो आप Array.indexOf का उपयोग कर सकते हैं । अन्यथा, मुझे लगता है कि आप अपने मूल कोड के समान कुछ को समाप्त करने जा रहे हैं।


16
function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
} 

अगर पाया जाता है, या नहीं मिला तो सरणी सूचकांक लौटाता है


16

हम इस स्निपेट (वस्तुओं, सरणियों, तारों के साथ काम करता है) का उपयोग करते हैं:

/*
 * @function
 * @name Object.prototype.inArray
 * @description Extend Object prototype within inArray function
 *
 * @param {mix}    needle       - Search-able needle
 * @param {bool}   searchInKey  - Search needle in keys?
 *
 */
Object.defineProperty(Object.prototype, 'inArray',{
    value: function(needle, searchInKey){

        var object = this;

        if( Object.prototype.toString.call(needle) === '[object Object]' || 
            Object.prototype.toString.call(needle) === '[object Array]'){
            needle = JSON.stringify(needle);
        }

        return Object.keys(object).some(function(key){

            var value = object[key];

            if( Object.prototype.toString.call(value) === '[object Object]' || 
                Object.prototype.toString.call(value) === '[object Array]'){
                value = JSON.stringify(value);
            }

            if(searchInKey){
                if(value === needle || key === needle){
                return true;
                }
            }else{
                if(value === needle){
                    return true;
                }
            }
        });
    },
    writable: true,
    configurable: true,
    enumerable: false
});

उपयोग:

var a = {one: "first", two: "second", foo: {three: "third"}};
a.inArray("first");          //true
a.inArray("foo");            //false
a.inArray("foo", true);      //true - search by keys
a.inArray({three: "third"}); //true

var b = ["one", "two", "three", "four", {foo: 'val'}];
b.inArray("one");         //true
b.inArray('foo');         //false
b.inArray({foo: 'val'})   //true
b.inArray("{foo: 'val'}") //false

var c = "String";
c.inArray("S");        //true
c.inArray("s");        //false
c.inArray("2", true);  //true
c.inArray("20", true); //false

15

यदि आप किसी ऐरे में किसी ऑब्जेक्ट के अस्तित्व के लिए बार-बार जाँच कर रहे हैं तो आपको शायद देखना चाहिए

  1. अपने सरणी में प्रविष्टि सॉर्ट करके हर समय सरणी को क्रमबद्ध रखना (नई वस्तुओं को सही जगह पर रखना)
  2. अद्यतन ऑब्जेक्ट्स को निकालें + सॉर्ट किए गए सम्मिलित ऑपरेशन के रूप में बनाएं और
  3. अपने में एक द्विआधारी खोज लुकअप का उपयोग करें contains(a, obj)

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

13

समाधान जो सभी आधुनिक ब्राउज़रों में काम करता है:

function contains(arr, obj) {
  const stringifiedObj = JSON.stringify(obj); // Cache our object to not call `JSON.stringify` on every iteration
  return arr.some(item => JSON.stringify(item) === stringifiedObj);
}

उपयोग:

contains([{a: 1}, {a: 2}], {a: 1}); // true

IE6 + समाधान:

function contains(arr, obj) {
  var stringifiedObj = JSON.stringify(obj)
  return arr.some(function (item) {
    return JSON.stringify(item) === stringifiedObj;
  });
}

// .some polyfill, not needed for IE9+
if (!('some' in Array.prototype)) {
  Array.prototype.some = function (tester, that /*opt*/) {
    for (var i = 0, n = this.length; i < n; i++) {
      if (i in this && tester.call(that, this[i], i, this)) return true;
    } return false;
  };
}

उपयोग:

contains([{a: 1}, {a: 2}], {a: 1}); // true

क्यों इस्तेमाल करें JSON.stringify?

Array.indexOfऔर Array.includes(साथ ही यहाँ अधिकांश उत्तर) केवल संदर्भ से तुलना करते हैं और मूल्य से नहीं।

[{a: 1}, {a: 2}].includes({a: 1});
// false, because {a: 1} is a new object

बक्शीश

गैर-अनुकूलित ES6 एक-लाइनर:

[{a: 1}, {a: 2}].some(item => JSON.stringify(item) === JSON.stringify({a: 1));
// true

नोट: मान के अनुसार वस्तुओं की तुलना करना बेहतर होगा यदि कुंजियाँ समान क्रम में हों, तो सुरक्षित रहने के लिए आप पहले इस तरह से पैकेज के साथ कुंजियों को क्रमबद्ध कर सकते हैं: https://www.npmjs.com/package/sort-keys


containsएक पूर्ण अनुकूलन के साथ फ़ंक्शन को अपडेट किया । इसे इंगित करने के लिए धन्यवाद itinance


कोड का यह विशेष हिस्सा IE6 में काम कर सकता है (परीक्षण नहीं किया गया), लेकिन IE ने IE9 तक ES5 का समर्थन नहीं किया।
मार्क रीड

प्रदर्शन कारणों से आपको स्ट्रिंग करने से बचना चाहिए। कम से कम आपको JSON से बचना चाहिए। हर लूप पर "obj" को लागू करें क्योंकि यह महंगा है और आपके आवेदन को धीमा कर देगा। इसके लिए आपको इसे अस्थायी चर में लूप से पहले कैप्चर करना चाहिए
8:14 पर itinance

1
@ बुद्धि अच्छा बिंदु। includesअपने सुझाव के साथ फ़ंक्शन को अपडेट करें । मैं अपने फंक्शन के साथ jsperf भागा हूं। यह लॉश के शामिलों की तुलना में लगभग 5 गुना धीमा है। हालांकि लॉश मूल्य से तुलना नहीं करता है और अंदर नहीं मिल सकता {a: 1}है [{a: 1}]। मुझे नहीं पता कि क्या कोई पुस्तकालय करता है। लेकिन मैं उत्सुक हूं अगर ऐसा करने के लिए कोई और अधिक जटिल तरीका नहीं है और न ही जटिल तरीके से।
इगोर बारबाशिन

देर से ध्यान दें: यह साथ काम नहीं करता है, कहते हैं, contains([{ a: 1, b: 2 }], { b: 2, a: 1 })क्योंकि कड़े ऑब्जेक्ट गुणों के क्रम को बनाए रखते हैं।
बंदर

1
@HereticMonkey, सच। यही कारण है कि मैंने sort-keysनीचे नोट जोड़ा
इगोर बारबाशिन

12

लॉश के कुछ फ़ंक्शन का उपयोग करें ।

यह संक्षिप्त है, सटीक है और इसमें क्रॉस प्लेटफॉर्म सपोर्ट है।

स्वीकृत उत्तर आवश्यकताओं को भी पूरा नहीं करता है।

आवश्यकताएँ: एक जावास्क्रिप्ट सरणी एक वस्तु होती है, यह पता लगाने के लिए सबसे संक्षिप्त और कुशल तरीके की सिफारिश करें।

स्वीकृत उत्तर:

$.inArray({'b': 2}, [{'a': 1}, {'b': 2}])
> -1

मेरी सिफारिश:

_.some([{'a': 1}, {'b': 2}], {'b': 2})
> true

टिप्पणियाँ:

$ .inArray यह निर्धारित करने के लिए ठीक काम करता है कि स्केलर की एक सरणी में एक स्केलर मान मौजूद है या नहीं ...

$.inArray(2, [1,2])
> 1

... लेकिन प्रश्न स्पष्ट रूप से यह निर्धारित करने के लिए एक कुशल तरीका पूछता है कि क्या ऑब्जेक्ट किसी सरणी में निहित है।

स्केलर और ऑब्जेक्ट दोनों को संभालने के लिए, आप ऐसा कर सकते हैं:

(_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)

10

ECMAScript 6 में खोज पर एक सुंदर प्रस्ताव है।

खोज विधि कॉलबैक फ़ंक्शन को सरणी में मौजूद प्रत्येक तत्व के लिए एक बार निष्पादित करती है, जब तक कि वह एक ऐसा स्थान न मिल जाए जहां कॉलबैक एक वास्तविक मूल्य देता है। यदि ऐसा कोई तत्व पाया जाता है, तो तुरंत उस तत्व का मान लौटाएं। अन्यथा, अपरिभाषित रिटर्न पाते हैं। कॉलबैक केवल उसी सरणी के अनुक्रमित के लिए लागू किया जाता है जिसने मान निर्दिष्ट किए हैं; यह उन अनुक्रमणिकाओं के लिए लागू नहीं किया गया है जिन्हें हटा दिया गया है या जिन्हें कभी मान निर्दिष्ट नहीं किए गए हैं।

यहाँ उस पर MDN प्रलेखन है।

खोज की कार्यक्षमता इस तरह काम करती है।

function isPrime(element, index, array) {
    var start = 2;
    while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) return false;
    }
    return (element > 1);
}

console.log( [4, 6, 8, 12].find(isPrime) ); // Undefined, not found
console.log( [4, 5, 8, 12].find(isPrime) ); // 5

आप इसे फंक्शन को परिभाषित करके ECMAScript 5 और नीचे में उपयोग कर सकते हैं ।

if (!Array.prototype.find) {
  Object.defineProperty(Array.prototype, 'find', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(predicate) {
      if (this == null) {
        throw new TypeError('Array.prototype.find called on null or undefined');
      }
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }
      var list = Object(this);
      var length = list.length >>> 0;
      var thisArg = arguments[1];
      var value;

      for (var i = 0; i < length; i++) {
        if (i in list) {
          value = list[i];
          if (predicate.call(thisArg, value, i, list)) {
            return value;
          }
        }
      }
      return undefined;
    }
  });
}


9

जबकि array.indexOf(x)!=-1ऐसा करने के लिए सबसे संक्षिप्त तरीका है (और पिछले एक दशक से गैर-इंटरनेट एक्सप्लोरर ब्राउज़र द्वारा समर्थित है ...), यह ओ (1) नहीं है, बल्कि ओ (एन) है, जो भयानक है। यदि आपकी सरणी नहीं बदल रही है, तो आप अपने सरणी को हैशटेबल में बदल सकते हैं, फिर करें table[x]!==undefinedया करें ===undefined:

Array.prototype.toTable = function() {
    var t = {};
    this.forEach(function(x){t[x]=true});
    return t;
}

डेमो:

var toRemove = [2,4].toTable();
[1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})

(दुर्भाग्य से, जब आप सरणी को "फ्रीज" करने के लिए एक Array.prototyp.contains बना सकते हैं और एक हैशटेबल को दो पंक्तियों में संग्रहीत कर सकते हैं। यह दो बार बाद में आपके सरणी को संपादित करने के लिए चुना जाता है, तो यह गलत परिणाम देगा। जावास्क्रिप्ट में अपर्याप्त हुक हैं। उदाहरण के लिए, आप अजगर के विपरीत इस स्थिति को बनाए रखते हैं।)


9

एक सेट का उपयोग कर सकते हैं जिसके पास "()" है:

function contains(arr, obj) {
      var proxy = new Set(arr);
      if (proxy.has(obj))
        return true;
      else
        return false;
    }

    var arr = ['Happy', 'New', 'Year'];
    console.log(contains(arr, 'Happy'));


5
मुझे लगता return proxy.has(obj)है कि इधर
उधर के

function contains(arr, obj) { return new Set(arr).has(obj); }
गॉर्डन बीन

8

उपयोग:

var myArray = ['yellow', 'orange', 'red'] ;

alert(!!~myArray.indexOf('red')); //true

डेमो

tilde ~इस बिंदु पर वास्तव में क्या करना है, यह जानने के लिए, इस प्रश्न को देखें कि जब कोई अभिव्यक्ति देता है तो एक टिल्ड क्या करता है?


5
यह पहले से ही पोस्ट किया गया था और आधे साल पहले इसे दोहराने की कोई आवश्यकता नहीं थी
शैडो विजार्ड इयर फॉर यू यू

3
दरअसल, इसे पोस्ट नहीं किया गया है। उत्तर के रूप में नहीं, बल्कि उत्तर के लिए एक टिप्पणी के रूप में, और तब भी यह स्पष्ट और संक्षिप्त नहीं है। इसे पोस्ट करने के लिए धन्यवाद, मीना गेब्रियल।
T.CK

6

ठीक है, आप परिणाम प्राप्त करने के लिए अपने कोड को अनुकूलित कर सकते हैं !

ऐसा करने के कई तरीके हैं जो क्लीनर और बेहतर हैं, लेकिन मैं सिर्फ आपके पैटर्न को प्राप्त करना चाहता था और उस उपयोग पर लागू करना चाहता था JSON.stringify, बस आपके मामले में ऐसा कुछ करना चाहिए:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (JSON.stringify(a[i]) === JSON.stringify(obj)) {
            return true;
        }
    }
    return false;
}

देर से ध्यान दें: यह साथ काम नहीं करता है, कहते हैं, contains([{ a: 1, b: 2 }], { b: 2, a: 1 })क्योंकि कड़े ऑब्जेक्ट गुणों के क्रम को बनाए रखते हैं।
बंदर

5

किसी भी तरह से सबसे अच्छा नहीं है, लेकिन मैं सिर्फ रचनात्मक और प्रदर्शनों की सूची में जोड़ रहा था।

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

Object.defineProperty(Array.prototype, 'exists', {
  value: function(element, index) {

    var index = index || 0

    return index === this.length ? -1 : this[index] === element ? index : this.exists(element, ++index)
  }
})


// Outputs 1
console.log(['one', 'two'].exists('two'));

// Outputs -1
console.log(['one', 'two'].exists('three'));

console.log(['one', 'two', 'three', 'four'].exists('four'));


यह नहीं तो आपको क्या उपयोग करना चाहिए?
bryc

@bryc शायद स्वीकृत समाधान, या यहाँ से कोई अन्य समाधान। यदि आप प्रदर्शन के लिए बहुत परवाह नहीं करते हैं, तो आप इसका इस्तेमाल कर सकते हैं
वर्गम

5

हैरानी की बात है कि इस सवाल में अभी भी नवीनतम वाक्यविन्यास नहीं है, मेरे 2 सेंट जोड़ रहा है।

मान लें कि हमारे पास अरेंज ऑबजेक्ट्स हैं और हम इसमें ओब्जेक्ट सर्च करना चाहते हैं।

Array.prototype। indexOf -> (रिटर्न इंडेक्स या -1 ) आमतौर पर एरे में तत्व के इंडेक्स को खोजने के लिए उपयोग किया जाता है। इसका उपयोग ऑब्जेक्ट खोजने के लिए भी किया जा सकता है, लेकिन केवल तभी काम करता है जब आप उसी ऑब्जेक्ट का संदर्भ दे रहे हों।

let obj = { name: 'Sumer', age: 36 };
let arrObj = [obj, { name: 'Kishor', age: 46 }, { name: 'Rupen', age: 26 }];


console.log(arrObj.indexOf(obj));// 0
console.log(arrObj.indexOf({ name: 'Sumer', age: 36 })); //-1

console.log([1, 3, 5, 2].indexOf(2)); //3

Array.prototype। शामिल है -> ( सही या गलत रिटर्न )

console.log(arrObj.includes(obj));  //true
console.log(arrObj.includes({ name: 'Sumer', age: 36 })); //false

console.log([1, 3, 5, 2].includes(2)); //true

Array.prototype। खोजें -> (कॉलबैक लेता है, सीबी में सही मूल्य / वस्तु लौटाता है)।

console.log(arrObj.find(e => e.age > 40));  //{ name: 'Kishor', age: 46 }
console.log(arrObj.find(e => e.age > 40)); //{ name: 'Kishor', age: 46 }

console.log([1, 3, 5, 2].find(e => e > 2)); //3

Array.prototype। findIndex -> (कॉलबैक लेता है, पहले मूल्य / ऑब्जेक्ट का इंडेक्स देता है जो CB में सही रिटर्न देता है)।

console.log(arrObj.findIndex(e => e.age > 40));  //1
console.log(arrObj.findIndex(e => e.age > 40)); //1

console.log([1, 3, 5, 2].findIndex(e => e > 2)); //1

चूँकि खोज और खोज के बाद कॉलबैक लेता है, हम सही स्थिति को रचनात्मक रूप से सेट करके किसी भी ऑब्जेक्ट (भले ही हमारे पास संदर्भ न हो) प्राप्त कर सकते हैं।


5

इस आवश्यकता का सरल समाधान उपयोग कर रहा है find()

यदि आप नीचे की तरह वस्तुओं का सरणी रखते हैं,

var users = [{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "admin"},
{id: "105", name: "user"}];

फिर आप जांच सकते हैं कि आपके मूल्य वाली वस्तु पहले से मौजूद है या नहीं

let data = users.find(object => object['id'] === '104');

यदि डेटा शून्य है, तो कोई व्यवस्थापक नहीं, अन्यथा यह नीचे की तरह मौजूदा ऑब्जेक्ट को वापस कर देगा।

{id: "104", name: "admin"}

फिर आप उस ऑब्जेक्ट के इंडेक्स को सरणी में खोज सकते हैं और नीचे दिए गए कोड का उपयोग करके ऑब्जेक्ट को बदल सकते हैं।

let indexToUpdate = users.indexOf(data);
let newObject = {id: "104", name: "customer"};
users[indexToUpdate] = newObject;//your new object
console.log(users);

आपको नीचे जैसा मूल्य मिलेगा

[{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "customer"},
{id: "105", name: "user"}];

आशा है कि यह किसी की मदद करेगा।


5

    function countArray(originalArray) {
     
    	var compressed = [];
    	// make a copy of the input array
    	var copyArray = originalArray.slice(0);
     
    	// first loop goes over every element
    	for (var i = 0; i < originalArray.length; i++) {
     
    		var count = 0;	
    		// loop over every element in the copy and see if it's the same
    		for (var w = 0; w < copyArray.length; w++) {
    			if (originalArray[i] == copyArray[w]) {
    				// increase amount of times duplicate is found
    				count++;
    				// sets item to undefined
    				delete copyArray[w];
    			}
    		}
     
    		if (count > 0) {
    			var a = new Object();
    			a.value = originalArray[i];
    			a.count = count;
    			compressed.push(a);
    		}
    	}
     
    	return compressed;
    };
    
    // It should go something like this:
    
    var testArray = new Array("dog", "dog", "cat", "buffalo", "wolf", "cat", "tiger", "cat");
    var newArray = countArray(testArray);
    console.log(newArray);

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