2014-11-02 15 views
5

Sto cercando di ottenere un risultato simile a questo: Miniors | Boys | 54kg - 62kg dove ogni valore delimitato da una pipe | proviene da una matrice che contiene un determinato "tipo di restrizione". Ad esempio: ageGroups, genders, weightClasses (come visto sopra).Dinamico annidato per cicli da risolvere con ricorsione

Il modo in cui sono in grado di ottenere questo risultato adesso è se faccio un codice fisso per i loopEachid (usando underscorejs), ma questo significa che devo ora quanti array devo ricorrere per ottenere il risultato desiderato . Questo funziona "fine":

var categories = []; 
_.each(ageGroups, function(ageGroup) { 
    _.each(gender, function(gender) { 
    _.each(weightClasses, function(weightClass) { 
     categories.push(ageGroup.name + ' | ' + gender.name + ' | ' + weightClass.name); 
     }); 
    }); 
}); 

L'uscita è un array (categorie) con tutte le possibili combinazioni delle matrici di restrizione.

Ora, il mio problema è che ho bisogno di un modo per fare lo stesso con un numero sconosciuto di matrici di restrizione. La mia ipotesi di una soluzione adeguata è ricorsione, MA non sono stato in grado di produrre tutto ciò che funziona in realtà dato che non sono in grado di avvolgere la mia testa intorno ricorsione appena ancora :)

un violino preparato con alcuni dati di test può essere trovato qui: jsFiddle. Il violino usa l'angolare per un semplice calcolo dei dati e il debug dell'output dei risultati e dei underscorejs per la gestione degli array.

+0

non Prova usare effetti collaterali (ad esempio 'push'ing su una matrice' categorie' globale), ma invece 'return' da ogni passo e usare' map' (e 'flatten') – Bergi

+0

Hmm .. Okey. Appiattire non sarà di alcuna utilità qui poiché ho bisogno di una combinazione dei diversi valori dai diversi array. Ma la mappa potrebbe essere qualcosa .. Anche se non riesco a vedere come risolverebbe il problema, mi trovo ad affrontare una quantità dinamica di matrici. Ti interessa elaborare? – aup

+0

Prova ad usare 'map' (anche in un modo non generico) e vedrai per cosa hai bisogno di' flatten'. Quindi, crea una funzione che utilizza i 'gruppi', l'indice del gruppo corrente (il" livello di nidificazione ") e i nomi correnti dei gruppi visitati. Il caso base (quando il livello di nidificazione ha raggiunto la lunghezza dei 'gruppi') restituirebbe quindi quei nomi correnti (uniti da' | '), il caso ricorsivo - lo capirai. – Bergi

risposta

2

Ho recentemente scritto una funzione ricorsiva per creare tutte le combinazioni di matrici. Dovresti tradurre i tuoi dati in una serie di array utilizzati dalla mia funzione, ma ciò non dovrebbe essere difficile.

Comunque, ecco il codice con un esempio eseguibile:

var v = [['Miniors','Kadettes','Juniors', 'Seniors'], ['Boys','Girls','Men','Women'],['54kg - 62kg','64kg - 70kg','71kg - 78kg','79kg - 84kg']]; 
 
var combos = createCombinations(v); 
 
for(var i = 0; i < combos.length; i++) { 
 
    document.getElementsByTagName("body")[0].innerHTML += combos[i] + "<br/>"; 
 
} 
 

 
function createCombinations(fields, currentCombinations) { 
 
    //prevent side-effects 
 
    var tempFields = fields.slice(); 
 

 
    //recursively build a list combinations 
 
    var delimiter = ' | '; 
 
    if (!tempFields || tempFields.length == 0) { 
 
    return currentCombinations; 
 
    } 
 
    else { 
 
    var combinations = []; 
 
    var field = tempFields.pop(); 
 

 
    for (var valueIndex = 0; valueIndex < field.length; valueIndex++) { 
 
     var valueName = field[valueIndex]; 
 

 
     if (!currentCombinations || currentCombinations.length == 0) { 
 
     var combinationName = valueName; 
 
     combinations.push(combinationName); 
 
     } 
 
     else { 
 
     for (var combinationIndex = 0; combinationIndex < currentCombinations.length; combinationIndex++) { 
 
      var currentCombination = currentCombinations[combinationIndex]; 
 
      var combinationName = valueName + delimiter + currentCombination; 
 
      combinations.push(combinationName); 
 
     } 
 
     } 
 
    } 
 
    return createCombinations(tempFields, combinations); 
 
    } 
 
}

+0

Grandi cose! Sembra molto carino, grazie! – aup

2
function iterate(lists, fn) 
{ 
    var values = []; 
    function process(listIndex) 
    { 
    var list = lists[listIndex]; 

    // no list? create the value 
    if (!list) 
    { 
     fn.apply(null, values); 
     return; 
    } 

    for (var i = 0; i < list.length; i++) 
    { 
     values[listIndex] = list[i]; 
     process(listIndex+1); 
    } 
    } 

    process(0); 
} 

qui è un esempio di lavoro in base ai dati di cui la tua domanda: http://jsbin.com/boqucu/2/edit

+0

Questo funziona perfettamente "out-of-the-box" per il mio caso specifico! Perché le persone stanno votando questo? Non vedo come mai posso usare questo in modo dinamico? La funzione che mette insieme il nome finale richiede una quantità specifica di parametri. Grazie! – aup

+0

almeno qualcuno mi dà qualche informazione. Aggiornerò la mia risposta Grazie. – lloiser

+0

Cose fantastiche! Ho appena cambiato la chiamata fn per passare semplicemente la matrice valori invece di fh.apply(). Penso che l'abbia fatto! Grazie ancora! – aup