首页 > 解决方案 > 在没有内置函数的情况下更改字符串中字母的大小写

问题描述

编写一个函数,在字符串(作为第一个参数传递)中搜索字符(作为第二个参数传递)并更改在字符串中找到的该字符的所有实例的大小写。禁止使用内置函数。如何解决?

 function changeCaseOfLetter(text, character) {

    let output = "";
    for(let i = 0; i < text.length; i++) {

        if(text[i] === character) {
       let charCode = text.charCodeAt(i);

       if(charCode >= 65 && charCode <= 90) {
            output += String.fromCharCode(charCode + 32);
       }
       if(charCode >= 97 && charCode <= 122) {
           output += String.fromCharCode(charCode - 32);
       }
       if(charCode < 65 || charCode > 122) {
           output += text[i];
       }
    }
    else {
        output += text[i];
    }
}
    return output;
}

在此处输入图像描述

标签: javascript

解决方案


编辑注意:测试您的代码后,它可以工作。或者至少,根据问题陈述工作:

编写一个函数,在字符串(作为第一个参数传递)中搜索字符(作为第二个参数传递)并更改在字符串中找到的该字符的所有实例的大小写

所以,我想对于第一个失败的单元测试,测试本身被破坏了,而不是你的代码。执行changeCaseOfLetter('bRA', 'a') 返回bRA,因为源字符串不包含小写a字母。

但是,如果您实际上被禁止使用库函数(并且string.charCodeAt()显然string.fromCharCode()是库函数),请退回到自汇编语言时代以来库编写者一直在做这种事情的方式:编写查找表。

function toggleCase( s , target ) {
    let r = '';
    for (const c of s ) {
        r += c === target   // If the current char matches the target char,
           ? toggle[c] || c // - look it up in the map or fall back to the current char,
           : c ;            // - otherwise, leave it as-is
    }
    return r;
}

const toggle = {
    'A':'a' , 'B':'b' , 'C':'c' , // 'D'–'W' mappings to lowercase omitted for brevity
    'X':'x' , 'Y':'y' , 'Z':'z' ,
    'a':'A' , 'b':'B' , 'c':'C' , // 'd'–'w' mappings to uppercase omitted for brevity
    'x':'X' , 'y':'Y' , 'z':'Z' ,
}

这对于 US-ASCII 来说是相当轻松的,但是如果您需要支持 Unicode,问题空间会迅速变得更大

另一个小编辑:将您的代码稍微重构为更简单的函数,每个函数都做一件事可以使您的代码更容易理解,更容易测试。

重构代码的 5 分钟给了我以下信息。一切都做一件简单的事情,很容易测试。更重要的是,它更容易理解,因为小而简单的函数是用意图命名的:

function changeCaseOfLetter(text, character) {
    if (!isUpper(character) && !isLower(character) ) {
        throw new Error(`ERROR: '${character}' must be an upper- or lower-case character`);
    }

    let output   = "";
    const toggle = isUpper(character) ? toLower
                 : isLower(character) ? toUpper
                 :                      c => c
                 ;

    for (const c of text ) {
        output += c === character ? toggle(c) : c ;
    }

    return output;
}

const isUpper = c => c >= 'A' && c <= 'Z';
const isLower = c => c >= 'a' && c <= 'z';

const toLower = c => isUpper(c) ? shift(c, +32 ) : c ;
const toUpper = c => isLower(c) ? shift(c, -32 ) : c ;

const shift = (c,distance) => String.fromCharCode( c.charCodeAt() + distance ) ;

推荐阅读