2015-12-30 12 views
5

Verwenden Sie reduce, um zu ermitteln, wie oft sich ein Element in einem Array befindet. Das Array könnte rekursiv Arrays enthalten.Verwenden Sie reduce, um das Array zu verkürzen.

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

bar(foo, 4) zurückkehren würde 3.

+2

In Ihrem Beispiel, warum würde 'bar (foo," a ")' '' 'zurückgeben, obwohl' "a" 'nur zweimal in seiner Eingabe auftritt? – Codor

+0

@NorCallKnockOut Danke für die Klarstellung. – Codor

+0

foo ist kein Objekt, es ist ein Array – edc65

Antwort

4

diese ein Array.prototype.reduce mit Versuchen.

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))

Die Funktion f ist eine rekursive Funktion. Wir durchlaufen alle Elemente und reduzieren sie auf eine Zahl. Die Funktion würde auch für alle inneren Arrays aufgerufen werden, und für die Nicht-Array-Elemente prüfen wir sie einfach so, dass sie dem gewünschten Element entsprechen.

+0

Was macht der zweite Parameter der ersten Rückkehr? die, 0); – NorCalKnockOut

+1

Ahh. Genial. Das ist wirklich sauber. Vielen Dank – NorCalKnockOut

+0

@NorCalKnockOut zuerst, 's' würde initialisiert werden zu init-Wert (0), dann wird es die Funktion auf allen Elementen aufrufen und speichern Sie den Rückgabewert wieder' s' und rufen Sie die Funktion auf das nächste Element .So funktioniert 'reduce'. –

4

Sie können alle Einzelteile mit einem Anruf rechnen mit Array.prototype.forEach()

Die forEach() Methode führt eine bereitgestellte Funktion einmal pro Array-Element.

Und überprüfen Sie, ob das Element ein Array ist, dann wird die Funktion erneut mit dem Array als Parameter aufgerufen.

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

OP fragt nach einer rekursiven Funktion. –

+4

@ HiI'mFrogatto \t Dies nennt "count" aus "count"; ist das nicht die Definition von rekursiv? –

+0

Oh Entschuldigung, das habe ich einfach nicht gesehen. ':)' –

2

Wenn Sie also eine Rekursion wollen (Und es wird in jedem Browser funktionieren):

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

Hier ist eine andere funktionelle Art der Interpretation, die keinen externen Zustand erfordert, wenn auch ineffizient wäre.

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 Verwenden Sie Anzahl des Auftretens jedes Element mit diesem Code zählen:

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

So kann Funktion foo wie folgt realisiert werden:

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

Obwohl dies lös Ion ist nicht rekursiv Ich finde es erwähnenswert.

Verwandte Themen