2015-12-30 10 views
5

को छोटा करने के लिए कम करें का उपयोग करें किसी आइटम को किसी सरणी में कितनी बार ढूंढने के लिए कम करें। सरणी में रिकर्सली के अंदर सरणी हो सकती है।सरणी

var foo = [ 
    1, 
    [2, 3, 4], 
    4, [5,6,7], 4 
]; 

bar(foo, 4) लौट 3.

+2

आपके उदाहरण में, 'बार (foo, "a") 'return' 3' क्यों होगा, हालांकि "" एक "' इनपुट में केवल दो बार होता है? स्पष्टीकरण के लिए – Codor

+0

@NorCallKnockOut धन्यवाद। – Codor

+0

foo कोई ऑब्जेक्ट नहीं है, यह एक सरणी है – edc65

उत्तर

4

यह एक Array.prototype.reduce का उपयोग करें।

var foo = [1, [2, 3, 4], 4, [5, 6, 7], 4]; 
 

 
function f(arr, item) { 
 
    return arr.reduce(function (s, i) { 
 
    if (Array.isArray(i)) return s+f(i, item); 
 
    return s+(i==item?1:0); 
 
    }, 0); 
 
} 
 

 
console.log(f(foo, 4))

समारोह f एक पुनरावर्ती कार्य है। हम सभी वस्तुओं पर लूप करते हैं और उन्हें एक नंबर पर कम करते हैं। फ़ंक्शन को सभी आंतरिक सरणीओं पर भी बुलाया जाएगा, और गैर-सरणी वस्तुओं के लिए, हम उन्हें वांछित आइटम के बराबर होने के लिए जांचते हैं।

+0

पहली वापसी का दूसरा पैरामीटर क्या है? 0,; – NorCalKnockOut

+1

आह। बहुत बढ़िया। यह वास्तव में साफ है। धन्यवाद – NorCalKnockOut

+0

@NorCalKnockOut पहले, 's' को init मान (0) में प्रारंभ किया जाएगा, फिर यह सभी तत्वों पर फ़ंक्शन को कॉल करने जा रहा है और वापसी मान को फिर से' s' पर संग्रहीत करेगा और फ़ंक्शन को अगले तत्व पर कॉल करेगा ।इस प्रकार 'कम करें' काम करता है। –

4

आप Array.prototype.forEach()

साथ forEach() विधि सरणी तत्व प्रति एक बार एक प्रदान की फ़ंक्शन निष्पादित एक कॉल के साथ सभी वस्तुओं भरोसा कर सकते हैं होगा।

और यदि कोई तत्व सरणी है, तो जांच करें, फिर फ़ंक्शन को पैरामीटर के रूप में सरणी के साथ फिर से बुलाया जाता है।

var foo = ["a", ["b", "c", "d"], "a"], 
 
    object = {}; 
 

 
function count(a, o) { 
 
    a.forEach(function (b) { 
 
     if (Array.isArray(b)) { 
 
      count(b, o); 
 
     } else { 
 
      o[b] = (o[b] || 0) + 1; 
 
     } 
 
    }) 
 
} 
 

 
count(foo, object); 
 
document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');

+0

ओपी एक रिकर्सिव फ़ंक्शन मांग रहा है। –

+4

@ HiI'mFrogatto \t यह 'गिनती' के भीतर से 'गिनती' को कॉल करता है; क्या यह रिकर्सिव की परिभाषा नहीं है? –

+0

ओह क्षमा करें, मैंने अभी यह नहीं देखा। ':)' –

2

तो अगर आप एक प्रत्यावर्तन चाहते हैं (और यह किसी भी ब्राउज़र में काम करेंगे):

var foo = [ 
    "a", 
    ["b", "c", "d"], 
    "a" 
]; 

function bar(arr, item) { 
    var count = 0; 
    if (arr.length == 0) { 
     return 0; 
    } 

    for (var i = 0, l = arr.length; i < l; i++) { 
     var v = arr[i]; 
     if (typeof v === "string") { 
      if (v === item) { 
       count++; 
      } 
     } else { 
      count = count + bar(v, item); 
     } 
    } 

    return count; 
} 

console.log(bar(foo, "a")); 
2

यहाँ, व्याख्या यह है कि एक बाहरी राज्य की आवश्यकता नहीं है की एक और कार्यात्मक प्रकार है, हालांकि अधिक अक्षम हो जाएगा।

var foo = [ 
 
    "a", 
 
    ["b", "c", "d"], 
 
    ["a", "b"], 
 
    "a" 
 
]; 
 

 
function flatten(arr){ 
 
    return arr.reduce(function(ret, curr){ 
 
    return ret.concat(Array.isArray(curr) ? flatten(curr) : [ curr ]); 
 
    }, []); 
 
} 
 

 
function filterBy(arr, val){ 
 
    return arr.filter(function(item){ 
 
    return item === val; 
 
    }) 
 
} 
 

 
console.log(flatten(foo)); 
 
console.log(filterBy(flatten(foo), 'a'));
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>

1

underscore का उपयोग करके आप इस कोड के साथ प्रत्येक तत्व की घटना की संख्या की गणना कर सकते हैं:

_.countBy(_.flatten(array), _.identity) 

तो समारोह foo इस तरह लागू किया जा सकता:

function bar(foo, element){ 
    return _.countBy(_.flatten(foo), _.identity)[element]; 
} 
var foo = ["a", ["b", "c", "d"], "a"] 
console.log(bar(foo, "a")); 

हालांकि यह समाधान आयन रिकर्सिव नहीं है मुझे इसका उल्लेख करने लायक लगता है।