【问题标题】:convert a string to a string of numbers representing where each letter is located in the alphabet ('a' is 1, 'z' is 26)将字符串转换为数字字符串,表示每个字母在字母表中的位置('a' 是 1,'z' 是 26)
【发布时间】:2018-06-16 13:01:54
【问题描述】:

我需要创建一个函数alphabetIndexer,它接受一个字符串作为参数并返回一个数字字符串,表示每个字母在字母表中的位置('a' 是1,'z' 是26)。如果字符为大写,则将其位置乘以 2。字符串中所有非字母的字符都应被忽略。

function alphabetIndexer(str){
    let alphabet = 'abcdefghigklmnopqrstuvwxyz';
    let arr = [];
    for(let i = 0; i < str.length; i++){
        if(alphabet.includes(str[i].toLowerCase())){
            if(str[i] === str[i].toUpperCase()){
                arr.push(alphabet.indexOf((str[i] +1)*2))
            } else {
            arr.push(alphabet.indexOf(str[i]) +1);
            }
        }
    }
            return arr.join(' ');
}

我无法将大写字母位置乘以 2;

在测试用例“Hello World”中,它应该返回“16 5 12 12 15 46 15 17 12 4” 但我的函数返回 [ -1, 5, 12, 12, 15, -1, 15, 18, 12, 4 ]

【问题讨论】:

标签: javascript


【解决方案1】:

你已经有了一个很好的开始,你只是把括号弄错了。这个:

arr.push(alphabet.indexOf((str[i] +1)*2))

应该是

arr.push((alphabet.indexOf(str[i]) +1)*2)

如果这样会更清楚:

  • 您将 str[i] 放入变量中,而不是每次都查找它
  • 运算符周围已使用空格

:-)

即:

arr.push((alphabet.indexOf(ch) + 1) * 2)

第二个问题是您只在执行includes 检查时才执行toLowerCase 的事情,而在您执行indexOf 时不会稍后执行。你需要在你浏览alphabet的所有三个地方都这样做:

function alphabetIndexer(str) {
  let alphabet = 'abcdefghigklmnopqrstuvwxyz';
  let arr = [];
  for (let i = 0; i < str.length; i++) {
    if (alphabet.includes(str[i].toLowerCase())) {
      if (str[i] === str[i].toUpperCase()) {
        arr.push((alphabet.indexOf(str[i].toLowerCase()) + 1) * 2); // ***
      } else {
        arr.push(alphabet.indexOf(str[i].toLowerCase()) + 1);       // ***
      }
    }
  }
  return arr.join(' ');
}
console.log(alphabetIndexer("Hi there"));

对于它的价值,这里有一些我会做的小改动(不改变你的整体方法):

"use strict";
function alphabetIndexer(str) {
  let alphabet = 'abcdefghigklmnopqrstuvwxyz';
  let arr = [];
  for (let ch of str) { // Strings are iterable
    // Only search `alphabet` once
    let index = alphabet.indexOf(ch.toLowerCase());
    if (index !== -1) {
      if (ch === ch.toUpperCase()) {
        arr.push((index + 1) * 2);
      } else {
        arr.push(index + 1);
      }
    }
  }
  return arr.join(' ');
}
console.log(alphabetIndexer("Hi there"));

您也可以考虑将const 用于您永远不会更改的“变量”(有趣的是,这就是代码中的全部内容;更改arr状态 并不会更改变量arr)。

【讨论】:

  • 谢谢!即使修正了括号错误,函数仍然返回'-2 5 12 12 15 -2 15 18 12 4' 第一个-2应该是16,第二个-2应该是46;
  • Eddie :) 感谢您提供有关 codePointAt() 的提示 - 我现在正在研究它。并感谢您清理和更容易阅读该功能的版本:)
  • @AliciaK - 出现第二个错误(我无意中在上面的版本中修复了该错误)。您只在执行includes 检查时才执行toLowerCase 的操作,但在您执行indexOf 时不会稍后执行。您需要在您查看alphabet (jsfiddle.net/ykoxLn43) 的所有三个地方执行此操作。 (这就是为什么只这样做一次,如上所述,是更好的主意。)
【解决方案2】:
arr.push(alphabet.indexOf((str[i] +1)*2))

这显然是哪里出错了。你确定你的 * 2 应该在 indexOf 参数内吗?试试这个:

arr.push((alphabet.indexOf(str[i]) +1)*2);

编辑:想想为什么它给你-1也是一个好主意。我不太确定,因为我自己不是 JavaScript 专家。

【讨论】:

  • 对不起。看来我需要晚间咖啡了。
【解决方案3】:

您可以使用.charCodeAt() 获取ASCII 值,然后从0 中减去偏移量。

const CAPS_OFFSET  = 64;
const LOWER_OFFSET = 96;
const ALPHA_ONLY   = /[a-zA-Z]/;

console.log( alphabetIndexer('Hello World') );


function alphabetIndexer(str) {  

  let arr = Array.from(str, letter=>{
    if (!ALPHA_ONLY.test(letter)) return;
    let ascii = letter.charCodeAt(0)
    return ascii > LOWER_OFFSET ? ascii - LOWER_OFFSET : (ascii - CAPS_OFFSET)*2;
  });
  
  return arr.join(' ')
}

【讨论】:

  • 模式[...str].map(cb) 使用Array.from(str, cb) 会更好,因为它同时使用可迭代对象和映射。
  • 更新了你的精通建议
猜你喜欢
  • 2018-06-07
  • 1970-01-01
  • 2017-02-06
  • 2017-12-24
  • 2018-02-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
  • 1970-01-01
相关资源
最近更新 更多