2016-08-04 70 views
3

我想找到一種有效的方法來收集所有可能的連續字符串連接從一個字符串數組的數組,不包括具有重複部分的字符串。例如:如何從字符串數組數組中收集所有可能的連續字符串連接?

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

其中結果將是

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

(注意的是,雖然,例如,["pq, ffnn, ffnn, ab"]是一個可能的組合,但並不包括在結果,因爲它包含一個副本)。
問題是我需要知道數組的長度並相應地編寫多個嵌套函數。但是我需要一些能自動檢測這個長度的函數,並返回所需的結果。也許可以用遞歸來重寫上面的函數,但我不確定這是否是解決這個問題的最佳方法。

+3

備註:當你不使用它的時候使用'map'價值是沒有意義的,還有一點額外的工作(它爲你創建了一個數組,然後你就扔掉了)。如果不使用返回值,請使用'forEach'。 –

+0

只會有兩個維度?例如,包含數組的數組?不是包含數組數組的數組? –

+1

@TJCrowder:是的,我會盡量保持它「包含字符串數組的數組」。 –

回答

-2

您可以使用四個for each循環嵌套。

我設法得到它。 它應該適用於n-subarrays。

看一看,讓我知道它是否無法正常工作。

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

該代碼與我的問題中的代碼具有完全相同的問題:我將不得不爲不同的長度編寫不同的函數。 –

+0

@lyrically我工作的代碼將適用於n個子數組。我誤以爲你的問題,對不起。 – Krandalf

+0

@lyrically邪惡,請檢查我所做的更改請。 – Krandalf

-1

如果我理解正確的話,給出的字符串n的數組的數組,你希望所有可能的排列m這樣的列表

  1. 所有im[i]n[i]的其中之一
  2. 對於所有的ij,如果i!= jm[i]!= m[j]

那麼,在半休息。

首先,考慮一個函數combo,給定一個字符串數組的數組,產生滿足(1)的數組的數組。你怎麼寫?

combo在一個空輸入數組上產生一個只包含一個空數組的數組。

combo在非空輸入數組上可以通過取「head」(數組的第一個元素)並依次應用來自頭部的每個字符串並預先應用於返回值爲combo的每個數組「尾巴」(其餘部分沒有頭部)。

現在通過該列表並刪除重複條目。

編輯:給出的一些其他建議的Tolstoivian長,我想我會發布我的答案,它使用Underscore庫:

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>

(這是遠離CPU的最有效使用 - 但電腦比電腦程序員便宜很多)。

相關問題