【问题标题】:Format casing of names when first letter is repeated第一个字母重复时名称的格式大小写
【发布时间】:2019-03-04 21:40:04
【问题描述】:

我有一个函数,它接受一个名称数组并返回一个新数组,每个名称的第一个字母转换为大写(其余字母小写)。

function capMe(arr) {
  let newArr = [];
  arr.forEach(function(name) {
    name = name.replace(name[0], name[0].toUpperCase());
    for(let i = 1; i < name.length; i++) {
        name = name.replace(name[i], name[i].toLowerCase());
    }
    newArr.push(name);
});
return newArr;
}

这在绝大多数情况下都有效。例如,如果我这样调用函数:

console.log(capMe(['jACKSON', 'pAM', 'wiLliAm']));

我将收到&gt; Array ["Jackson", "Pam", "William"] 的所需输出。

但是,有一种情况下此功能不起作用。如果我用重复第一个字母的名称调用函数,则每个字母都将是小写,除了第二次出现的字母。

例如,如果我在前面的示例中添加gEORGANN,我将收到以下输出:

&gt; Array ["georGann", "Jackson", "Pam", "William"]

我该如何解决这个问题?

【问题讨论】:

    标签: javascript arrays string replace


    【解决方案1】:

    您当前的逻辑并没有按照您的想法进行。考虑在每个名称的循环中出现的以下行:

    name = name.replace(name[i], name[i].toLowerCase());
    

    这只是将等于name[i]第一个 字符替换为该字母的小写版本。这是使用输入gEORGANN 摆脱逻辑的方式。首先,你大写第一个g,得到GEORGANN。然后,当循环到达第四个位置时,即大写 G,它将 first G 替换为小写 g。这给我们留下了gEORGANN,但这不是您想要的。原因是replace 只是第一次出现。

    可能可以通过全部替换而不是替换来解决此问题。但是为什么不直接将大写的第一个字符与小写字符串的其余部分连接起来:

    arr = ['georGann', 'jACKSON', 'pAM', 'wiLliAm'];
    newArr = [];
    arr.forEach(function(name) {
        newName = name.charAt(0).toUpperCase() + name.substring(1).toLowerCase()
        newArr.push(newName);
    });
    console.log(arr);
    console.log(newArr);

    【讨论】:

    • OP 可能要考虑添加一个由“”或“-”分隔的字符串,用于具有多个或奇怪名字的人。
    • "这是替换所有等于 name[i] 的字符" — 不,没有 g 标志,它正在替换 first
    • @TimBiegeleisen — 不要假设反对票的来源。
    【解决方案2】:

    给你:

    const capMe = (arr = []) => {
      return arr.map((name) => {
        const [first, ...rest] = name;
        return `${first.toUpperCase()}${rest.join('').toLowerCase()}`;
      });
    }
    
    console.log(capMe(['foo', 'foZBaz']));

    【讨论】:

    • NMD(= 不是我的反对意见),但也许您还应该尝试解释为什么 OP 当前的方法失败了。
    • 是的。我有点太仓促了。但不值得投反对票。
    • 我同意 +1。工作代码通常不值得反对 +1。
    【解决方案3】:

    您的编码逻辑很好。问题是操作的顺序。请看下文;

    function capMe(arr) {
        let newArr = [];
        arr.forEach(function(name) {
          name = name.toLowerCase();
          name = name.replace(name[0], name[0].toUpperCase());
          newArr.push(name);
        });
       return newArr;
    }
    console.log(capMe(['gEORGANN', 'pAM', 'wiLliAm', 'AA']));

    【讨论】:

    • 这可能会巧合地解决 OP 的问题,但它可能不是最好的方法。
    • 如果输入中有两个相同的大写字符,这将不起作用。
    • @TimBiegeleisen 正确。我指出他的逻辑是正确的,这是有原因的。这不是最好的做法。但这个答案更符合他/她的思路
    • 阅读上面昆汀的评论 :-)
    猜你喜欢
    • 1970-01-01
    • 2016-10-20
    • 2018-04-03
    • 2017-09-17
    • 2013-11-29
    • 2019-07-01
    • 2019-08-19
    • 2011-01-20
    相关资源
    最近更新 更多