2013-06-20 100 views
1

我正在尝试创建一个可以返回带有单词字符的数组的函数。它需要在数组中保存一些双字母。我有一个包含双字母的数组。我有一个单词列表(somethimes大)。现在的问题是,它将第一个字母保存2次,并将字母中的双字节保存为字母。该函数本身运行在一个从json对象获取单词的循环中。功能是以我能想到的方式完成的,但如果有更好的方法(显然),请告诉我如何。更改字符串中的双字母

功能:字母

var word = 'voorheen'; 
var doubles = ['aa', 'oo', 'ee', 'ie', 'oe', 'eu', 'uu', 'au', 'ou', 'ui', 'ng', 'ch', 'ij']; 
var letters = getLetters(word, doubles); 
console.log(letters); 

function getLetters(word, doubles) { 
var letters = []; 
var specials = []; 
var indexes = []; 
for(var s=0;s<doubles.length;s++) { 
    if(word.indexOf(doubles[s]) != -1) { 
     specials.push(doubles[s]); 
     indexes.push(word.indexOf(doubles[s])); 
     console.log('specials: ' + specials);   
     console.log('indexes: ' + indexes);   
    } 
} 
for(var i=0;i<word.length;i++) { 
    if(specials.length>0) { 
     for(var j=0;j<specials.length;j++) { 
      if(i<indexes[j]) { 
       letters.push(word[i]); 
       console.log('i: ' + i); 
       console.log('j: ' + j); 
       console.log('letter: ' + word[i]); 
      }  
      if(i==indexes[j]) { 
       letters.push(specials[j]); 
       console.log('i: ' + i); 
       console.log('j: ' + j); 
       console.log('letter: ' + word[i]);     
      } 
      if(i>indexes[j] + specials[j].length) { 
       letters.push(word[i]); 
       console.log('i: ' + i); 
       console.log('j: ' + j); 
       console.log('letter: ' + word[i]);     
      } 

     } 
    } 
    else { 
     letters.push(word[i]); 
    }  
} 
return letters; 
} 

铬日志输出:

["v", "v", "oo", "o", "o", "r", "h", "h", "e", "ee", "e", "n"] 

虽然我想:

["v", "oo", "r", "h", "ee", "n"] 
+1

为什么jQuery的标签? – Xotic750

+0

什么是输入和你想要什么输出? –

+0

因为我没有问题,使用jquery,如果它更容易创建一个功能,做我所需要的。 – Zeebats

回答

2
var word = 'voorheen'; 
var doubles = ['aa','oo','ee','ie','oe','eu','uu','au','ou','ui','ng','ch','ij']; 
var letters = word.match(new RegExp(doubles.join("|")+"|.","g")) || []; 

的正则表达式捕捉尽可能多的(除非特别宣布不合理),所以两个字母的组合优先于匹配任何单个字符的.

红利点,因为这可以被扩展到包括任何长度的组合:P

+3

捕获组是不必要的,并且不要忘记尾部的|| ||。 []'匹配尝试后(空字) – Bergi

+0

谢谢。我真的应该开始学习正则表达式。 – Zeebats

+0

@Bergi谢谢。 –

1

这里是一个解决方案,应在不regexs和POJS工作

的Javascript

function stringToFormattedArray(string) { 
    var doubles = ['aa', 'oo', 'ee', 'ie', 'oe', 'eu', 'uu', 'au', 'ou', 'ui', 'ng', 'ch', 'ij'], 
     result = [], 
     chars, 
     pair; 

    while (string) { 
     pair = string.slice(0, 2); 
     if (doubles.indexOf(pair) !== -1) { 
      result.push(pair); 
      string = string.slice(2); 
     } else { 
      result.push(pair.split("")[0]); 
      string = string.slice(1); 
     } 
    } 

    return result; 
} 

console.log(stringToFormattedArray("voorheen")); 

输出

["v", "oo", "r", "h", "ee", "n"] 

jsfiddle

注意:Array.prototype.indexOf可以通过MDN或es5_shim提供的垫片进行垫片。或者,你当然可以循环通过手动的阵列和执行===

更新:不Array.prototype.indexOf

的Javascript

function stringToFormattedArray(string) { 
    var doubles = ['aa', 'oo', 'ee', 'ie', 'oe', 'eu', 'uu', 'au', 'ou', 'ui', 'ng', 'ch', 'ij'], 
     length = doubles.length, 
     result = [], 
     chars, 
     pair, 
     i; 

    while (string) { 
     pair = string.slice(0, 2); 

     i = 0; 
     while (i < length) { 
      if (pair === doubles[i]) { 
       result.push(pair); 
       string = string.slice(2); 
       break; 
      } 

      i += 1; 
     } 

     if (i === length) { 
      result.push(pair.split("")[0]); 
      string = string.slice(1); 
     } 
    } 

    return result; 
} 

console.log(stringToFormattedArray("voorheen")); 

jsfiddle

更新:纯利益着想,我创建了一个jsperf测试正则表达式版本与上述特定字符串“vorheen”。

1

那么,在specials的迭代中,如果它不在当前的indexes[j]上,则每次都会推送这些字母。由于您的specials有两名成员,每封信都会翻倍。

要解决这个问题,您需要一个标志,不管当前字母是否应该在该循环中设置。顺便说一下,你的指数方法无论如何都是有缺陷的,因为它无法应对重复双倍(例如oohoo)。更好:

function getLetters(word, doubles) { 
    var letters = []; 
    for (var i=0; i<word.length; i++) { 
     var next = word.slice(i, i+2); 
     if (doubles.indexOf(next) >= 0) { 
      letters.push(next); 
      i++; 
     } else 
      letters.push(word.charAt(i)); 
    } 
    return letters; 
} 

基于正则表达式匹配器就会简单得多:

var word = 'voorheen', 
    letters = word.match(/aa|oo|ee|ie|oe|eu|uu|au|ou|ui|ng|ch|ij|\S/g) || []; 
0

我想你也使它过于复杂。

刚刚尝试的东西如下:http://jsfiddle.net/jHjkQ/

var word = 'voorheen'; 
var doubles = ['aa', 'oo', 'ee', 'ie', 'oe', 'eu', 'uu', 'au', 'ou', 'ui', 'ng', 'ch', 'ij']; 
var result = []; 
for(var i=0; i < word.length;i++) { 
    var nextI = i + 1; 
    //as double it must be first if you going to implement triple add above this line... 
    if (nextI < word.length && doubles.indexOf(word[i] + "" + word[nextI]) > -1) { 
     result.push(doubles[doubles.indexOf(word[i] + "" + word[nextI])]); 
     i++; //double ignore next one 
    } 
    else { 
     result.push(word[i]); 
    } 
} 

console.log(result); 
+0

这依赖于浏览器知道'Array.prototype.indexOf',这在老版本的IE中是不正确的。 –

+0

在这种情况下,您可以使用jQuery.inArray(“aa”,arr)代替。 –

+0

因为,当然,jQuery是一切的答案。特别是当[Vanilla JS](http://vanilla-js.com/)中有一个无限简单的解决方案时, –