2011-07-20 91 views
3

我想寫一個自定義字符串劃分功能,這是難度比我本來期望。的Javascript分割陣列

基本上,我通過在一個字符串,該字符串將分裂的值的陣列,並且它會返回子字符串數組,移除空的,並且包括它分裂上的值。如果字符串可以在同一個地方由兩個不同的值進行分割,較長的一個優先。

也就是說,

split("Go ye away, I want some peace && quiet. & Thanks.", ["Go ", ",", "&&", "&", "."]); 

應該返回

["Go ", "ye away", ",", " I want some peace ", "&&", " quiet", ".", " ", "&", " Thanks", "."] 

你能想到一個相當簡單的算法,這個的?如果有一個內置的方式在Javascript做到這一點(我不認爲有),這將是更好的。

+0

應該' 「你們 」'和'「 離開」'分裂?似乎這應該只是一個,如果我理解。 –

+0

您是否想將「」作爲您的分隔符之一?你的輸出似乎表明,但你的輸入沒有。 –

+0

@kingjiv是的,那是一個錯誤。現在應該修好了。 –

回答

5

喜歡的東西this

function mySplit(input, delimiters) { 

    // Sort delimiters array by length to avoid ambiguity 
    delimiters.sort(function(a, b) { 
     if (a.length > b.length) { return -1; } 
     return 0; 
    } 

    var result = []; 

    // Examine input one character at a time 
    for (var i = 0; i < input.length; i++) { 
     for (var j = 0; j < delimiters.length; j++) { 
      if (input.substr(i, delimiters[j].length) == delimiters[j]) { 

       // Add first chunk of input to result 
       if (i > 0) { 
        result.push(input.substr(0, i)); 
       } 
       result.push(delimiters[j]); 

       // Reset input and iteration 
       input = input.substr(i + delimiters[j].length); 
       i = 0; 
       j = 0; 
      } 
     } 
    } 

    return result; 
} 

var input  = "Go ye away, I want some peace && quiet. & Thanks."; 
var delimiters = ["Go ", ",", "&&", "&", "."]; 

console.log(mySplit(input, delimiters)); 
// Output: ["Go ", "ye away", ",", " I want some peace ", 
//   "&&", " quiet", ".", " ", "&", " Thanks", "."] 
+0

它的工作,很酷!我感到尷尬......這是我自己的解決方案的三分之一大小無法正常工作。 –

+1

在衝突的情況下,這不會優先考慮更長的分隔符(我認爲這是一個問題的要求)。如果在分隔符數組中切換「&&」和「&」,它將在「&」上分開而不是「&&」 – Bob

+0

的確如此。它具有從左到右的優先權。如果操作系統需要不同的語義,他可以按照長度對分隔符列表進行排序。但是這並沒有在問題中說明,並且在給定的分隔符列表中沒有含糊之處。 –

3

精確解問:

function megasplit(toSplit, splitters) { 
    var splitters = splitters.sorted(function(a,b) {return b.length-a.length}); 
                  // sort by length; put here for readability, trivial to separate rest of function into helper function 
    if (!splitters.length) 
     return toSplit; 
    else { 
     var token = splitters[0]; 
     return toSplit 
      .split(token)    // split on token 
      .map(function(segment) { // recurse on segments 
       return megasplit(segment, splitters.slice(1)) 
      }) 
      .intersperse(token)  // re-insert token 
      .flatten()    // rejoin segments 
      .filter(Boolean); 
    } 
} 

演示:

> megasplit(
     "Go ye away, I want some peace && quiet. & Thanks.", 
     ["Go ", ",", "&&", "&", "."] 
) 
["Go ", "ye away", ",", " I want some peace ", "&", "&", " quiet", ".", " ", "&", " Thanks", "."] 

機械(可重複使用!):

Array.prototype.copy = function() { 
    return this.slice() 
} 
Array.prototype.sorted = function() { 
    var copy = this.copy(); 
    copy.sort.apply(copy, arguments); 
    return copy; 
} 
Array.prototype.flatten = function() { 
    return [].concat.apply([], this) 
} 
Array.prototype.mapFlatten = function() { 
    return this.map.apply(this,arguments).flatten() 
} 
Array.prototype.intersperse = function(token) { 
    // [1,2,3].intersperse('x') -> [1,'x',2,'x',3] 
    return this.mapFlatten(function(x){return [token,x]}).slice(1) 
} 

注:


如果一個跟隨典型分裂行爲1-襯墊:

Array.prototype.mapFlatten = function() { 
    ... 
} 
function megasplit(toSplit, splitters) { 
    return splitters.sorted(...).reduce(function(strings, token) { 
     return strings.mapFlatten(function(s){return s.split(token)}); 
    }, [toSplit]); 
} 

3內膽,如果上面是難以閱讀:

Array.prototype.mapFlatten = function() { 
    ... 
} 
function megasplit(toSplit, splitters) { 
    var strings = [toSplit]; 
    splitters.sorted(...).forEach(function(token) { 
     strings = strings.mapFlatten(function(s){return s.split(token)}); 
    }); 
    return strings; 
} 
+0

這是「確切的解決方案要求」?您的輸出不匹配。 –