यह पता लगाने का सबसे संक्षिप्त और कारगर तरीका क्या है कि किसी JavaScript सरणी में कोई मान है या नहीं?
यह एकमात्र तरीका है जिसे मैं करना जानता हूं:
function contains(a, obj) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
}
क्या इसे पूरा करने का कोई बेहतर और संक्षिप्त तरीका है?
29 जवाब
आधुनिक ब्राउज़र में Array#includes
< है /a>, जो बिल्कुल करता है और व्यापक रूप से समर्थित है:
console.log(['joe', 'jane', 'mary'].includes('jane')); //true
आप Array#indexOf
का भी इस्तेमाल कर सकते हैं, जो कम है प्रत्यक्ष, लेकिन पुराने ब्राउज़र के लिए पॉलीफ़िल की आवश्यकता नहीं है।
console.log(['joe', 'jane', 'mary'].indexOf('jane') >= 0); //true
कई ढांचे भी इसी तरह के तरीकों की पेशकश करते हैं:
- jQuery:
$.inArray(value, array, [fromIndex])
- Underscore.js:
_.contains(array, value)
(इसे_.include
और_.includes
के नाम से भी जाना जाता है) ) - डोजो टूलकिट:
dojo.indexOf(array, value, [fromIndex, findLast])
- प्रोटोटाइप:
array.indexOf(value)
- MooTools:
array.indexOf(value)
- MochiKit:
findValue(array, value)
- एमएस अजाक्स:
array.indexOf(value)
- विस्तार:
Ext.Array.contains(array, value)
- लोडाश:
_.includes(array, value, [from])
(यह_.contains
4.0.0 से पहले है) - रामदा:
R.includes(value, array)
ध्यान दें कि कुछ चौखटे इसे एक फ़ंक्शन के रूप में लागू करते हैं, जबकि अन्य फ़ंक्शन को सरणी प्रोटोटाइप में जोड़ते हैं।
Array.include
भी होता है जो एक बूलियन लौटाता है
array.indexOf(object) != -1
का उपयोग कर सकते हैं
inArray
एक फ़ंक्शन के लिए एक भयानक नाम है जो तत्व की अनुक्रमणिका देता है, और -1
यदि यह अस्तित्व में नहीं है। मुझे उम्मीद है कि एक बुलियन वापस आ जाएगा।
2019 से अपडेट: यह उत्तर 2008 (11 वर्ष पुराना!) से है और आधुनिक JS उपयोग के लिए प्रासंगिक नहीं है। वादा किया गया प्रदर्शन सुधार उस समय के ब्राउज़र में किए गए बेंचमार्क पर आधारित था। यह आधुनिक JS निष्पादन संदर्भों के लिए प्रासंगिक नहीं हो सकता है। यदि आपको एक आसान समाधान की आवश्यकता है, तो अन्य उत्तरों की तलाश करें। यदि आपको सर्वोत्तम प्रदर्शन की आवश्यकता है, तो प्रासंगिक निष्पादन वातावरण में अपने लिए बेंचमार्क।
जैसा कि अन्य ने कहा है, सरणी के माध्यम से पुनरावृत्ति शायद सबसे अच्छा तरीका है, लेकिन यह सिद्ध किया गया है a> कि घटते 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
indexOf
हो सकता है, लेकिन यह "जावास्क्रिप्ट एक्सटेंशन" है ईसीएमए -262 मानक के लिए, जैसे यह मानक के अन्य कार्यान्वयन में मौजूद नहीं हो सकता है।"
उदाहरण:
[1, 2, 3].indexOf(1) => 0
["foo", "bar", "baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1
AFAICS Microsoft नहीं करता है em> इसके लिए किसी प्रकार का विकल्प प्रदान करते हैं, लेकिन यदि आप चाहें तो Internet Explorer (और अन्य ब्राउज़र जो indexOf
का समर्थन नहीं करते) में सरणियों में समान कार्यक्षमता जोड़ सकते हैं, जैसे कि त्वरित Google खोज से पता चलता है (उदाहरण के लिए, यह वाला)।
ईसीएमएस्क्रिप्ट 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
के विपरीत, जो सख्त समानता तुलना का उपयोग करता है , includes
SameValueZero समानता एल्गोरिथ्म। इसका मतलब है कि आप पता लगा सकते हैं कि क्या किसी सरणी में NaN
शामिल है:
[1, 2, NaN].includes(NaN); // true
इसके अलावा indexOf
के विपरीत, includes
लापता सूचकांकों को नहीं छोड़ता है:
new Array(5).includes(undefined); // true
वर्तमान में यह अभी भी एक मसौदा है लेकिन पॉलीफिल्ड हो सकता है इसे सभी ब्राउज़रों पर काम करने के लिए।
शीर्ष उत्तर आदिम प्रकार के होते हैं लेकिन यदि आप यह पता लगाना चाहते हैं कि क्या किसी सरणी में कुछ विशेषता के साथ ऑब्जेक्ट है, तो Array.prototype.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 सहायता तालिका
Array.indexOf
का JavaScript 1.6 संगत कार्यान्वयन यहां दिया गया है:
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;
};
}
[].indexOf
, Array.prototype.indexOf
का शॉर्टहैंड है। हमारे पागल-रक्षात्मक जावास्क्रिप्ट प्रोग्रामर हर कीमत पर देशी प्रोटोटाइप का विस्तार करने से बचते हैं।
[].indexOf
एक नई सरणी नहीं बना रहा है और फिर indexOf
तक पहुंच रहा है, जबकि Array.prototype.indexOf
सीधे प्रोटोटाइप तक पहुंचता है?
[].indexOf === Array.prototype.indexOf
(फ़ायरबग में इसे आज़माएं), लेकिन इसके विपरीत [].indexOf !== Array.indexOf
।
उपयोग:
function isInArray(array, search)
{
return array.indexOf(search) >= 0;
}
// Usage
if(isInArray(my_array, "my_value"))
{
//...
}
x ? true : false
आमतौर पर बेमानी है। यह यहां पर है।
array.indexOf(search) >= 0
पहले से ही एक बूलियन है। बस return array.indexOf(search) >= 0
।
JavaScript Array
ऑब्जेक्ट का विस्तार करना वास्तव में एक बुरा विचार है क्योंकि आप for-in
लूप में नई प्रॉपर्टी (अपनी कस्टम विधियां) पेश करते हैं जो मौजूदा स्क्रिप्ट को तोड़ सकती हैं। कुछ साल पहले Prototype लाइब्रेरी के लेखकों को अपने पुस्तकालय कार्यान्वयन को फिर से इंजीनियर करना पड़ा था ताकि वे केवल इस तरह की बात।
यदि आपको अपने पृष्ठ पर चल रहे अन्य जावास्क्रिप्ट के साथ संगतता के बारे में चिंता करने की आवश्यकता नहीं है, तो इसके लिए जाएं, अन्यथा, मैं अधिक अजीब, लेकिन सुरक्षित फ्री-स्टैंडिंग फ़ंक्शन समाधान की अनुशंसा करता हूं।
एक लाइन:
function contains(arr, x) {
return arr.filter(function(elem) { return elem == x }).length > 0;
}
array.filter(e=>e==x).length > 0
array.some(e=>e==x)
के बराबर है लेकिन some
अधिक कुशल है
मैं निम्नलिखित का उपयोग करता हूं:
Array.prototype.contains = function (v) {
return this.indexOf(v) > -1;
}
var a = [ 'foo', 'bar' ];
a.contains('foo'); // true
a.contains('fox'); // false
function contains(a, obj) {
return a.some(function(element){return element == obj;})
}
Array.prototype.some() को ईसीएमए में जोड़ा गया था 5वें संस्करण में -262 मानक
contains = (a, obj) => a.some((element) => element === obj))
के रूप में छोटा किया जा सकता है
उम्मीद है कि तेज द्विदिश indexOf
/ lastIndexOf
विकल्प
2015
जबकि नई विधि शामिल है बहुत है अच्छा, समर्थन अभी के लिए मूल रूप से शून्य है।
यह लंबे समय से है कि मैं धीमी indexOf/lastIndexOf फ़ंक्शंस को प्रतिस्थापित करने के तरीके के बारे में सोच रहा था।
शीर्ष उत्तरों को देखते हुए, एक प्रदर्शनकारी तरीका पहले ही मिल चुका है। उनमें से मैंने @Damir Zekic द्वारा पोस्ट किए गए contains
फ़ंक्शन को चुना जो सबसे तेज़ होना चाहिए। लेकिन इसमें यह भी कहा गया है कि बेंचमार्क 2008 से हैं और इसलिए पुराने हैं।
मैं while
को for
से भी अधिक पसंद करता हूं, लेकिन किसी विशेष कारण के लिए मैंने लूप के साथ फ़ंक्शन लिखना समाप्त कर दिया। यह while --
के साथ भी किया जा सकता है।
मैं उत्सुक था अगर मैं इसे करते समय सरणी के दोनों किनारों की जांच करता हूं तो पुनरावृत्ति बहुत धीमी थी। जाहिरा तौर पर नहीं, और इसलिए यह फ़ंक्शन शीर्ष वोट वाले लोगों की तुलना में लगभग दो गुना तेज है। जाहिर है यह देशी से भी तेज है। यह एक वास्तविक दुनिया के माहौल में है, जहां आप कभी नहीं जानते कि आप जो मूल्य खोज रहे हैं वह शुरुआत में है या सरणी के अंत में है।
जब आप जानते हैं कि आपने किसी सरणी को एक मान के साथ धकेल दिया है, तो lastIndexOf का उपयोग करना शायद सबसे अच्छा समाधान है, लेकिन अगर आपको बड़े सरणियों से यात्रा करनी है और परिणाम हर जगह हो सकता है, तो चीजों को तेज करने के लिए यह एक ठोस समाधान हो सकता है।
द्विदिशात्मक अनुक्रमणिकाOf/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/bidirectionindexof
परीक्षण के रूप में मैंने 100k प्रविष्टियों के साथ एक सरणी बनाई।
तीन प्रश्न: शुरुआत में, मध्य में और सरणी के अंत में।
मुझे आशा है कि आपको भी यह दिलचस्प लगेगा और प्रदर्शन का परीक्षण करेंगे।
नोट: जैसा कि आप देख सकते हैं कि मैंने contains
फ़ंक्शन को इंडेक्सऑफ और 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/bidirectionindexof/2
function inArray(elem,array)
{
var len = array.length;
for(var i = 0 ; i < len;i++)
{
if(array[i] == elem){return i;}
}
return -1;
}
यदि पाया जाता है तो सरणी अनुक्रमणिका लौटाता है, या -1 यदि नहीं मिलता है
हम इस स्निपेट का उपयोग करते हैं (वस्तुओं, सरणियों, तारों के साथ काम करता है):
/*
* @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
यदि आप JavaScript 1.6 या बाद के संस्करण (फ़ायरफ़ॉक्स 1.5 या बाद के संस्करण) का उपयोग कर रहे हैं तो आप का उपयोग कर सकते हैं Array.indexOf। अन्यथा, मुझे लगता है कि आप अपने मूल कोड के समान कुछ समाप्त करने जा रहे हैं।
यदि आप किसी सरणी में किसी वस्तु के अस्तित्व के लिए बार-बार जाँच कर रहे हैं, तो आपको शायद इस पर गौर करना चाहिए
- अपने एरे में सम्मिलन सॉर्ट करके सरणी को हर समय क्रमबद्ध रखना सही जगह)
- वस्तुओं को हटाने के रूप में अद्यतन करें + सॉर्ट किए गए सम्मिलित ऑपरेशन और
- अपने
contains(a, obj)
में बाइनरी खोज लुकअप का उपयोग करें।
समाधान जो सभी आधुनिक ब्राउज़रों में काम करता है:
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
आईई6+ समाधान:
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 का धन्यवाद।
लॉश के some फ़ंक्शन का उपयोग करें।
यह संक्षिप्त, सटीक है और इसमें शानदार क्रॉस प्लेटफॉर्म सपोर्ट है।
स्वीकृत उत्तर आवश्यकताओं को भी पूरा नहीं करता है।
आवश्यकताएं: यह पता लगाने के लिए सबसे संक्षिप्त और कुशल तरीका सुझाएं कि क्या किसी जावास्क्रिप्ट सरणी में कोई वस्तु है।
स्वीकृत उत्तर:
$.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)
प्रदर्शन
आज 2020.01.07 मैं 15 चुने हुए समाधानों के लिए MacOs HighSierra 10.13.6 पर Chrome v78.0.0, Safari v13.0.4 और Firefox v71.0.0 पर परीक्षण करता हूं। निष्कर्ष
JSON
,Set
और आश्चर्यजनक रूप सेfind
(K,N,O) पर आधारित समाधान सभी ब्राउज़रों पर सबसे धीमे हैं- es6
includes
(F) केवल क्रोम पर तेज है for
(C,D) औरindexOf
(G,H) पर आधारित समाधान छोटे और बड़े सरणियों पर सभी ब्राउज़रों पर काफी तेज़ हैं, इसलिए शायद वे कुशल समाधान के लिए सबसे अच्छा विकल्प हैं- समाधान जहां लूप के दौरान सूचकांक घटता है, (बी) शायद धीमा है क्योंकि सीपीयू कैश काम करता है।
- मैं बड़े सरणी के लिए परीक्षण भी चलाता हूं जब खोजा गया तत्व सरणी लंबाई के 66% की स्थिति पर था, और
for
(सी, डी, ई) पर आधारित समाधान समान परिणाम देता है (~ 630 ऑप्स/सेकंड - लेकिन सफारी पर ई और फ़ायरफ़ॉक्स सी और डी की तुलना में 10-20% धीमा था)
परिणाम
विवरण
मैं 2 परीक्षण मामलों का प्रदर्शन करता हूं: 10 तत्वों के साथ सरणी के लिए, और 1 मिलियन तत्वों के साथ सरणी। दोनों ही मामलों में हम खोजे गए तत्व को सरणी के बीच में रखते हैं।
let log = (name,f) => console.log(`${name}: 3-${f(arr,'s10')} 's7'-${f(arr,'s7')} 6-${f(arr,6)} 's3'-${f(arr,'s3')}`)
let arr = [1,2,3,4,5,'s6','s7','s8','s9','s10'];
//arr = new Array(1000000).fill(123); arr[500000]=7;
function A(a, val) {
var i = -1;
var n = a.length;
while (i++<n) {
if (a[i] === val) {
return true;
}
}
return false;
}
function B(a, val) {
var i = a.length;
while (i--) {
if (a[i] === val) {
return true;
}
}
return false;
}
function C(a, val) {
for (var i = 0; i < a.length; i++) {
if (a[i] === val) return true;
}
return false;
}
function D(a,val)
{
var len = a.length;
for(var i = 0 ; i < len;i++)
{
if(a[i] === val) return true;
}
return false;
}
function E(a, val){
var n = a.length-1;
var t = n/2;
for (var i = 0; i <= t; i++) {
if (a[i] === val || a[n-i] === val) return true;
}
return false;
}
function F(a,val) {
return a.includes(val);
}
function G(a,val) {
return a.indexOf(val)>=0;
}
function H(a,val) {
return !!~a.indexOf(val);
}
function I(a, val) {
return a.findIndex(x=> x==val)>=0;
}
function J(a,val) {
return a.some(x=> x===val);
}
function K(a, val) {
const s = JSON.stringify(val);
return a.some(x => JSON.stringify(x) === s);
}
function L(a,val) {
return !a.every(x=> x!==val);
}
function M(a, val) {
return !!a.find(x=> x==val);
}
function N(a,val) {
return a.filter(x=>x===val).length > 0;
}
function O(a, val) {
return new Set(a).has(val);
}
log('A',A);
log('B',B);
log('C',C);
log('D',D);
log('E',E);
log('F',F);
log('G',G);
log('H',H);
log('I',I);
log('J',J);
log('K',K);
log('L',L);
log('M',M);
log('N',N);
log('O',O);
This shippet only presents functions used in performance tests - it not perform tests itself!
सरणी छोटा - 10 तत्व
आप अपनी मशीन में परीक्षण कर सकते हैं यहां
बड़े सरणी - 1.000.000 तत्व
आप अपनी मशीन में परीक्षण कर सकते हैं यहां
ईसीएमएस्क्रिप्ट 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
आप इसका उपयोग ईसीएमएस्क्रिप्ट 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;
}
});
}
जबकि array.indexOf(x)!=-1
ऐसा करने का सबसे संक्षिप्त तरीका है (और दशकों से गैर-इंटरनेट एक्सप्लोरर ब्राउज़रों द्वारा समर्थित है...), यह O(1) नहीं, बल्कि O(N) है, जो कि है भयानक। यदि आपकी सरणी नहीं बदल रही है, तो आप अपने सरणी को हैशटेबल में बदल सकते हैं, फिर 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})
(दुर्भाग्य से, जब आप एक सरणी बना सकते हैं। उदाहरण के लिए, आप इस स्थिति को पायथन के विपरीत रखते हैं।)
उपयोग:
var myArray = ['yellow', 'orange', 'red'] ;
alert(!!~myArray.indexOf('red')); //true
यह जानने के लिए कि इस समय tilde
~
क्या करते हैं, इस प्रश्न को देखें टिल्ड क्या करता है जब यह किसी एक्सप्रेशन से पहले आता है?।
कोई भी सेट का उपयोग कर सकता है, जिसमें "है(है) )":
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'));
return proxy.has(obj)
if-else कथन के साथ दो पंक्तियों की तुलना में बहुत साफ है
function contains(arr, obj) { return new Set(arr).has(obj); }
ठीक है, आप परिणाम प्राप्त करने के लिए बस अपना अनुकूलित कोड कर सकते हैं!
ऐसा करने के कई तरीके हैं जो क्लीनर और बेहतर हैं, लेकिन मैं सिर्फ आपका पैटर्न प्राप्त करना चाहता था और 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 })
के साथ काम नहीं करता है, क्योंकि कड़े ऑब्जेक्ट्स गुणों के क्रम को बनाए रखते हैं।
हैरानी की बात है कि इस प्रश्न में अभी भी मेरे 2 सेंट जोड़कर नवीनतम वाक्यविन्यास नहीं जोड़ा गया है।
मान लें कि हमारे पास arrObj ऑब्जेक्ट्स की सरणी है और हम इसमें obj खोजना चाहते हैं।
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.ढूंढें -> (कॉलबैक लेता है, पहले वैल्यू/ऑब्जेक्ट देता है जो CB में सही होता है)।
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
चूंकि फाइंड एंड फाइंडइंडेक्स कॉलबैक लेता है, इसलिए हम सही स्थिति को रचनात्मक रूप से सेट करके सरणी से किसी भी वस्तु (भले ही हमारे पास संदर्भ न हो) प्राप्त कर सकते हैं।
इस आवश्यकता का सरल समाधान 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"}];
उम्मीद है कि यह किसी की मदद करेगा।
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);
यहां बताया गया है कि प्रोटोटाइप यह कैसे करता है:
/**
* Array#indexOf(item[, offset = 0]) -> Number
* - item (?): A value that may or may not be in the array.
* - offset (Number): The number of initial items to skip before beginning the
* search.
*
* Returns the position of the first occurrence of `item` within the array — or
* `-1` if `item` doesn't exist in the array.
**/
function indexOf(item, i) {
i || (i = 0);
var length = this.length;
if (i < 0) i = length + i;
for (; i < length; i++)
if (this[i] === item) return i;
return -1;
}
यह भी देखें कि वे कैसे यहां देखें। इसे बांधकर रखें।
इसका एक पैरामीटर है: वस्तुओं की एक सरणी संख्या। सरणी में प्रत्येक वस्तु में दो पूर्णांक गुण होते हैं जिन्हें x और y द्वारा दर्शाया जाता है। फ़ंक्शन को सरणी में ऐसी सभी वस्तुओं की गिनती वापस करनी चाहिए जो numbers.x == numbers.y
को संतुष्ट करती हैं
var numbers = [ { x: 1, y: 1 },
{ x: 2, y: 3 },
{ x: 3, y: 3 },
{ x: 3, y: 4 },
{ x: 4, y: 5 } ];
var count = 0;
var n = numbers.length;
for (var i =0;i<n;i++)
{
if(numbers[i].x==numbers[i].y)
{count+=1;}
}
alert(count);
for (var i = 0; i < n; i++) { if (numbers[i].x == (numbers[i] + 1).x) { count += 1; } }
~[1,2,3].indexOf(4)
0 लौटाएगा जो कि असत्य के रूप में मूल्यांकन करेगा, जबकि~[1,2,3].indexOf(3)
वापस आएगा -3 जो सत्य के रूप में मूल्यांकन करेगा।~
वह नहीं है जिसे आप बूलियन में बदलने के लिए उपयोग करना चाहते हैं, इसके लिए आपको!
की आवश्यकता है। लेकिन इस मामले में आप -1 के साथ समानता की जांच करना चाहते हैं, इसलिए फ़ंक्शन समाप्त हो सकता हैreturn [1,2,3].indexOf(3) === -1;
~
एक बाइनरी नहीं है, यह अलग-अलग मूल्य के प्रत्येक बिट को उलट देगा।[1,2,3].indexOf(4)
वास्तव में रिटर्न -1 . जैसा कि @mcfedr ने बताया,~
बिटवाइज है -नहीं ऑपरेटर, ES5 11.4.8 देखें। बात यह है कि, चूंकि-1
के द्विआधारी प्रतिनिधित्व में केवल 1 होता है, इसका पूरक0
है, जिसका मूल्यांकन असत्य के रूप में होता है। किसी अन्य संख्या का पूरक अशून्य होगा, इसलिए सत्य है। तो,~
ठीक काम करता है और अक्सरindexOf
के संयोजन में प्रयोग किया जाता है।[[1,2],[3,4]].includes([3,4])
कहां है?