2011-07-20 90 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

这是“确切的解决方案要求”?您的输出不匹配。 –