2016-08-04 5 views
3

Ich versuche, eine effiziente Möglichkeit zu finden, alle möglichen zusammenhängenden String-Verkettungen aus einem Array von String-Arrays zu sammeln, mit Ausnahme von Strings mit doppelten Teilen. Beispiel:Wie werden alle möglichen zusammenhängenden String-Verkettungen aus einem Array von String-Arrays gesammelt?

var arr = [ 
 
     ["pq","bcd"], ["l", "ffnn", "xyz"], ["hm", "ffnn","ij"], ["ab","def","u","eeff"] 
 
    ]; 
 
    function f(a) { 
 
     var t = []; 
 
     a[a.length-4].forEach(function(i) { 
 
      a[a.length-3].forEach(function(j) { 
 
       if (j !== i) (
 
       a[a.length-2].forEach(function(k) { 
 
        if (k !== j && k !== i) (
 
        a[a.length-1].forEach(function(l) { 
 
         if (l !== k && l !== j && l !== i) 
 
         (t.push(i+","+j+","+k+","+l)); 
 
        }) 
 
        ) 
 
       }) 
 
       ) 
 
      }) 
 
     }); 
 
     return t; 
 
    }; 
 
    console.log(f(arr));

, wo das Ergebnis sein wird

["pq, l, hm, ab"], 
["pq, l, hm, def"], 
//...and so on... 
["bcd, xyz, ij, u"], 
["bcd, xyz, ij, eeff"] 

(dass während Hinweis, zB ["pq, ffnn, ffnn, ab"] eine mögliche Kombination ist, wird es im Ergebnis nicht enthalten, da es enthält ein Duplikat).
Das Problem ist, dass ich die Länge des Arrays kennen und mehrere verschachtelte Funktionen entsprechend schreiben muss. Aber ich brauche eine Funktion, die diese Länge automatisch erkennt und das gewünschte Ergebnis zurückgibt. Vielleicht ist es möglich, die obige Funktion mittels Rekursion neu zu schreiben, aber ich bin mir nicht sicher, ob dies der beste Ansatz für ein solches Problem wäre.

+3

Side note: Verwenden von 'map', wenn Sie nicht die Rückkehr verwenden Wert ist sinnlos und ein bisschen mehr Arbeit (es schafft ein Array für Sie, das Sie dann einfach wegwerfen). Verwenden Sie "forEach", wenn Sie den Rückgabewert nicht verwenden. –

+0

Es wird immer nur zwei Dimensionen geben? Z. B. ein Array, das Arrays enthält? Kein Array mit Arrays von Arrays? –

+1

@TJCrowder: Ja, ich werde versuchen, es so einfach wie "Array mit Arrays von Strings" zu halten. –

Antwort

-2

Sie könnten vier For-Schleifen verwenden, die ineinander verschachtelt sind.

Ich schaffte es zu bekommen. Es sollte für n-Subarrays funktionieren.

Schauen Sie und lassen Sie mich wissen, wenn es nicht richtig funktioniert.

var arr = [["pq","bcd"], ["l", "ffnn", "xyz"], ["hm", "ffnn","ij"], ["ab","def","u","eeff"]]; 
 
var length = arr.length; 
 

 
var noDuplicate = function (arr, possibleDuplicate) { 
 
    var arraySplit = arr.split(",") 
 
    for (var i = 0; i < arraySplit.length; i++) { 
 
     var arraySplitNoSpace = arraySplit[i].replace(' ', ''); 
 
     if (arraySplitNoSpace === possibleDuplicate) { 
 
      return false; 
 
     } 
 
    } 
 
    return true; 
 
}; 
 

 

 
var createLoops = function(original, adaptedOriginal, index) { // createLoops(arr, 0, 0); 
 

 
    var temporaryResults = []; 
 
    var temporary = adaptedOriginal ? adaptedOriginal : original[0]; 
 

 
    for (var i = 0; i < temporary.length; i++) { 
 
     for (var j = 0; j < original[index+1].length; j++) { 
 
      if (noDuplicate(temporary[i], original[index+1][j])) { 
 
       temporaryResults.push(temporary[i] + ", " + original[index+1][j]); 
 
      }; 
 
     }; 
 
    }; 
 

 
    if (index === length-2) { 
 
     var results = []; 
 
     for (var i = 0; i < temporaryResults.length; i++) { 
 
      results.push("[" + temporaryResults[i] + "]"); 
 
     } 
 
     return results; 
 
    } 
 

 
    else { 
 
     return createLoops(original, temporaryResults, index+1); 
 
    }; 
 
}; 
 

 
var result = createLoops(arr, 0, 0); 
 
console.log("result: " + result); 
 
console.log("result.length: " + result.length);

+3

Dieser Code hat genau das gleiche Problem wie der Code in meiner Frage: Ich werde verschiedene Funktionen für unterschiedliche Längen schreiben müssen. –

+0

@lyrically Ich arbeite an dem Code, der für n Subarrays funktionieren wird. Ich missverstanden deine Frage, tut mir leid. – Krandalf

+0

@lyrically böse, überprüfen Sie die Änderungen, die ich gemacht habe bitte. – Krandalf

-1

Wenn ich Sie richtig verstehe, da eine Reihe von Array von Strings n, möchten Sie eine Liste aller möglichen Anordnungen m so dass

  1. für alle i, m[i] ist eine von n[i]
  2. für alle i und j, wenn i! = j, m[i]! = m[j]

Nun, Pause in zwei Hälften.

Betrachten Sie zunächst eine Funktion combo, die bei einem Array von Strings ein Array der Arrays erzeugt, die (1) erfüllen. Wie schreibst du das?

combo auf einem leeren Eingabe-Array erzeugt ein Array, das nur ein leeres Array enthält.

combocombo könnte funktionieren, indem man den "Kopf" (das erste Element des Arrays) nimmt und jede Zeichenfolge vom Kopf der Reihe nach anwendet und jedem Array als Rückgabewert des aufrufenden combo vorlegt der "Schwanz" (der Rest der Eingabe ohne den Kopf).

Jetzt gehen Sie durch diese Liste und beseitigen Sie die Einträge mit Duplikaten.

Edit: die Tolstoivian Länge von einigen der anderen Vorschläge gegeben, dachte ich, ich würde meine Antwort veröffentlichen, die die Underscore Bibliothek verwendet:

const flatMap = (l, f) => _.flatten(_.map(l, f), true) 
 

 
const combo = a => a.length? 
 
    (v => flatMap(_.head(a), e => v.map(g => [e].concat(g)))) 
 
     (combo(_.tail(a))): 
 
    [[]]; 
 

 
const allUniqueCombos = a => combo(a).filter(n => _.uniq(n).length == n.length) 
 

 
var arr = [["pq","bcd"], ["l", "ffnn", "xyz"], 
 
      ["hm", "ffnn","ij"], ["ab","def","u","eeff"]]; 
 

 
console.log(JSON.stringify(allUniqueCombos(arr)))
<script src="http://underscorejs.org/underscore.js"></script>

(Dies ist weit entfernt von der effizientesten Nutzung der CPU - aber Computer sind immens billiger als Computer-Programmierer.)

Verwandte Themen