更改字符串中的双字母

时间:2013-06-20 15:46:20

标签: javascript

我正在制作(尝试制作)一个可以返回带有单词字符的数组的函数。它需要在数组中保存一些双字母作为一个字母。我有一个包含双字母的数组。我有一个单词列表(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"] 

4 个答案:

答案 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"]

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”。

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