我正在制作(尝试制作)一个可以返回带有单词字符的数组的函数。它需要在数组中保存一些双字母作为一个字母。我有一个包含双字母的数组。我有一个单词列表(somethimes big)。现在的问题是它将第一个字母保存了2次,并且它保存了名为letters的数组中单词的双字符。函数本身在一个循环中运行,该循环从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;
}
Chrome日志输出字母:
["v", "v", "oo", "o", "o", "r", "h", "h", "e", "ee", "e", "n"]
虽然我想:
["v", "oo", "r", "h", "ee", "n"]
答案 0 :(得分: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")) || [];
正则表达式尽可能地捕获(除非明确声明为ungreedy),因此双字母组合优先于匹配任何单个字符的.
。
奖励积分因为这可以扩展到包括任何长度的组合:p
答案 1 :(得分:1)
这是一个没有正则表达式和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"]
上
注意: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"));
上
更新:为了纯粹的利益,我创建了一个jsperf来测试正则表达式版本与上面的特定字符串“vorheen”。
答案 2 :(得分: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) || [];
答案 3 :(得分: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);