2012-09-10 31 views
22

के साथ सरणी को खोजने के लिए जावास्क्रिप्ट में कोई अनुक्रमणिका है, मुझे सरणी में पहले मान के अनुक्रमणिका की आवश्यकता है, जो एक कस्टम तुलना फ़ंक्शन से मेल खाता है।कस्टम तुलना फ़ंक्शन

बहुत अच्छा underscorej में "ढूंढें" फ़ंक्शन है जो पहला मान देता है जहां कोई फ़ंक्शन सत्य होता है, लेकिन मुझे इसकी आवश्यकता होगी जो इसके बजाय इंडेक्स लौटाए। क्या इंडेक्स का कोई संस्करण कहीं उपलब्ध है, जहां मैं तुलना करने के लिए इस्तेमाल किए गए फ़ंक्शन को पास कर सकता हूं?

किसी भी सुझाव के लिए धन्यवाद!

+1

मुझे लगता है कि सामान्य रूप में अपने दृष्टिकोण यहाँ गलत है: यहाँ एक polyfill, Mozilla Developer Network के सौजन्य से है। आप कार्यक्षमता को डिफ़ॉल्ट कार्यक्षमता को संशोधित नहीं करना चाहते हैं ('===' ओवरलोडिंग), आप अपनी कार्यक्षमता चाहते हैं (उदाहरण के लिए; 'myIndexOf')। पूर्व बाद की तुलना में अधिक विघटनकारी और खतरनाक है। – Christian

+2

लॉलाश में यह है http://lodash.com/docs#findIndex –

+1

यदि आपका लक्षित वातावरण ES2015 का समर्थन करता है (या आपके पास एक पारदर्शी चरण है, उदाहरण के लिए बेबेल के साथ), तो आप मूल Array.prototype.findIndex() का उपयोग कर सकते हैं। – craigmichaelmartin

उत्तर

26

यहाँ अंडरस्कोर जिस तरह से यह करना है - यह एक है कि पुनरावर्तक समारोह को स्वीकार करता है के साथ मुख्य अंडरस्कोर समारोह बढाती है:

// save a reference to the core implementation 
var indexOfValue = _.indexOf; 

// using .mixin allows both wrapped and unwrapped calls: 
// _(array).indexOf(...) and _.indexOf(array, ...) 
_.mixin({ 

    // return the index of the first array element passing a test 
    indexOf: function(array, test) { 
     // delegate to standard indexOf if the test isn't a function 
     if (!_.isFunction(test)) return indexOfValue(array, test); 
     // otherwise, look for the index 
     for (var x = 0; x < array.length; x++) { 
      if (test(array[x])) return x; 
     } 
     // not found, return fail value 
     return -1; 
    } 

}); 

_.indexOf([1,2,3], 3); // 2 
_.indexOf([1,2,3], function(el) { return el > 2; }); // 2 
+0

धन्यवाद का उपयोग करें, यह अच्छा है! –

+0

अंडरस्कोर ओवरकिल है। आप पूरी चीज को आईआईएफई में लपेटना चाहेंगे: आपने अभी वैश्विक वैरिएबल पर निर्भरता पेश की है। अगर आपके कोड में कोई बग है तो आपने _.indexOf का उपयोग करके सभी कोड दूषित कर दिए हैं। – 1983

+3

@mintsauce - ओपी ने अंडरस्कोर का संदर्भ दिया, यही कारण है कि मैंने अंडरस्कोर-आधारित समाधान की पेशकश की। वैश्विक संदर्भ w/r/t, यह एक स्निपेट है, ड्रॉप-इन मॉड्यूल नहीं; यह उपयोगकर्ता को यह लपेटने का काम है या अन्यथा इसे अपने आवेदन के लिए उपयुक्त तरीके से सेट अप करें। डब्ल्यू/आर/टी बग - सच है, यही कारण है कि मैं बग-फ्री कोड लिखना पसंद करता हूं :)। – nrabinowitz

7

आप कुछ इस तरह कर सकता है:

Array.prototype.myIndexOf = function(f) 
{ 
    for(var i=0; i<this.length; ++i) 
    { 
     if(f(this[i])) 
      return i; 
    } 
    return -1; 
}; 

ईसाई की टिप्पणी के बारे में: यदि आप एक अलग एक ही हस्ताक्षर और विभिन्न कार्यक्षमता के साथ एक कस्टम के साथ एक मानक JavaScript विधि ओवरराइड, बुरी बात होने की संभावना नहीं होगा । यह विशेष रूप से सच है यदि आप तृतीय पक्ष पुस्तकालयों में खींच रहे हैं जो मूल पर निर्भर हो सकते हैं, कहते हैं, Array.proto.indexOf। तो हाँ, आप शायद इसे कुछ और कहना चाहते हैं।

+2

चिंता के लिए धन्यवाद। मैं दूसरी संभावनाओं पर भी विश्वास करता हूं। ;) कृपया हाइलाइट करें क्यों 'Array.prototype.indexOf (फ़ंक्शन)' गलत दृष्टिकोण है, और मैं आपको वह अपवॉट दूंगा। – Christian

+0

फिक्स्ड। अच्छी पकड़। –

+0

इस के लिए धन्यवाद। मैं इसे ऐरे.प्रोटोटाइप में जोड़ने के बिना इसका उपयोग कर सकता था। –

0

का उपयोग कर को रेखांकित मैं कुछ के साथ आया था _.any का उपयोग कर अपने खोज कार्यान्वयन से नकल:

findIndex = function (obj, iterator, context) { 
    var idx; 
    _.any(obj, function (value, index, list) { 
     if (iterator.call(context, value, index, list)) { 
      idx = index; 
      return true; 
     } 
    }); 
    return idx; 
}; 

क्या आपको लगता है कि - आप किसी भी बेहतर समाधान है?

+0

मुझे नहीं पता कि '_.any' का क्या अर्थ है। मुझे लगता है कि आप कुछ ढांचे का उपयोग कर रहे हैं? यदि ऐसा है, तो हमारे लिए अच्छा रहें और हमें अपना रहस्य बताएं;)। – Christian

+0

जैसा कि प्रश्न में बताया गया है, underscore.js: http://underscorejs.org – billy

+1

आपको 'किसी भी' के साथ अतिरिक्त फ़ंक्शन का उपयोग नहीं करना चाहिए, यह विधि को धीमा कर देता है। बस एक साधारण फॉर-लूप – Bergi

1

जावास्क्रिप्ट सरणी विधि फिल्टर सरणी के एक सबसेट है कि से सच वापसी रिटर्न समारोह पारित किया गया।

var arr= [1, 2, 3, 4, 5, 6], 
first= arr.filter(function(itm){ 
    return itm>3; 
})[0]; 
alert(first); 

if you must support IE before #9 you can 'shim' Array.prototype.filter- 

Array.prototype.filter= Array.prototype.filter || function(fun, scope){ 
    var T= this, A= [], i= 0, itm, L= T.length; 
    if(typeof fun== 'function'){ 
     while(i<L){ 
      if(i in T){ 
       itm= T[i]; 
       if(fun.call(scope, itm, i, T)) A[A.length]= itm; 
      } 
      ++i; 
     } 
    } 
    return A; 
} 
+0

धन्यवाद, एक नया सबसेट सरणी बनाने से प्रदर्शन धीमा हो सकता है - आपको क्या लगता है? –

+0

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

1

ऐसे खोज फ़ंक्शन के बारे में कैसे?

(function() { 
    if (!Array.prototype._find) { 
    Array.prototype._find = function (value) { 
     var i = -1, j = this.length; 
     if (typeof(value)=="function") 
     for(; (++i < j) && !value(this[i]);); 
     else 
     for(; (++i < j) && !(this[i] === value);); 

     return i!=j ? i : -1; 
    } 
    } 
}()); 
1

यहाँ nrabinowitz के code की coffeescript संस्करण आता है।

# save a reference to the core implementation 
indexOfValue = _.indexOf 

# using .mixin allows both wrapped and unwrapped calls: 
# _(array).indexOf(...) and _.indexOf(array, ...) 
_.mixin ({ 
    # return the index of the first array element passing a test 
    indexOf: (array, test) -> 
     # delegate to standard indexOf if the test isn't a function 
     if (!_.isFunction(test)) 
      return indexOfValue(array, test) 
     # otherwise, look for the index 
     for item, i in array 
      return i if (test(item)) 
     # not found, return fail value 
     return -1 
}) 
3

के रूप में दूसरों का उल्लेख किया है, बहुत आसान अपनी खुद की है, जो आप छोटी और अपने विशेष उपयोग के मामले के लिए सरल रख सकते रोल करने:

// Find the index of the first element in array 
// meeting specified condition. 
// 
var findIndex = function(arr, cond) { 
    var i, x; 
    for (i in arr) { 
    x = arr[i]; 
    if (cond(x)) return parseInt(i); 
    } 
}; 

var moreThanTwo = function(x) { return x > 2 } 
var i = findIndex([1, 2, 3, 4], moreThanTwo) 

या यदि आप एक CoffeeScripter कर रहे हैं:

findIndex = (arr, cond) -> 
    for i, x of arr 
    return parseInt(i) if cond(x) 
6

a proposalArray.prototype.findIndex() हैर्मनी (ईसीएमएस्क्रिप्ट 6) में Array.prototype.findIndex() के लिए है। वर्तमान में यह फ़ायरफ़ॉक्स और सफारी में लागू किया गया है।

if (!Array.prototype.findIndex) { 
    Array.prototype.findIndex = 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++) { 
     value = list[i]; 
     if (predicate.call(thisArg, value, i, list)) { 
     return i; 
     } 
    } 
    return -1; 
    }; 
} 
+0

findIndex वास्तव में इस दौरान एक्मास्क्रिप्ट 2015 मानक में बनाया गया है, ऊपर @Husky द्वारा प्रदान किया गया लिंक देखें –