JS如何创建一个计算井号数量的函数

3

我是编程新手,现在需要回答以下问题:

创建一个函数,接收一个字符串参数,该字符串将包含一些类似 Twitter 中的提及和标签。

   E.g. "So excited to start  @coding on Monday! #learntocode #codingbootcamp"

该函数应返回一个描述发现的哈希标签和提及数量的对象:
   { hashtags: 2, mentions: 1 }
 

我创建的代码如下:

我创建的代码如下:

function countHashtagsAndMentions(str) {
   let split = str.split(" ");
    let count = 0
    for (let i = 9; i < str.length; i++) {
        let hash = split.filter(hashtag => hashtag.match(/#/g))
        if (hash === 1) {
          count ++
         }
        let total = {
        hash = count,
      }
    return hash
   }
 }

我的代码正在运行这个;

describe("countHashtagsAndMentions", () => {
  it("returns an object", () => {
    expect(typeof countHashtagsAndMentions("")).to.equal("object");
  });
  it("returns {hashtags: 0, mentions: 0} if it finds none", () => {
    expect(
      countHashtagsAndMentions(
        "hello this is a tweet guaranteed to get very little engagement"
      )
    ).to.eql({ hashtags: 0, mentions: 0 });
  });
  it("recognises no mentions", () => {
    expect(countHashtagsAndMentions("#yolo")).to.eql({
      hashtags: 1,
      mentions: 0
    });
  });
  it("recognises no hashtags", () => {
    expect(countHashtagsAndMentions("@yobo")).to.eql({
      hashtags: 0,
      mentions: 1
    });
  });
  it("finds multiple hashtags and mentions and returns that number", () => {
    expect(countHashtagsAndMentions("#yolo @bolo #golo")).to.eql({
      hashtags: 2,
      mentions: 1
    });
    expect(countHashtagsAndMentions("@boyo #goyo @loyo #zoyo")).to.eql({
      hashtags: 2,
      mentions: 2
    });
    expect(
      countHashtagsAndMentions(
        '"So excited to start at @northcoders on Monday! #learntocode #codingbootcamp"'
      )
    ).to.eql({ hashtags: 2, mentions: 1 });
  });
});

大家有没有什么建议可以让我的代码正常工作?


让 hashTagCount = "周一开始 @coding,感到非常兴奋!#learntocode #codingbootcamp"。split("#").length - 1; 你能检查一下吗? - Learner
同样地,您也可以检查提及次数。 - Learner
进行一些基本的调试。你甚至没有尝试创建预期的对象。如果不熟悉如何使用控制台日志记录,现在是学习的好时机。有很多资源和教程可以学习基本的调试方法。 - charlietfl
编辑不会删除问题。 - General Grievance
3个回答

2
一个简单的循环就可以了。由于您使用的是ES2015+语法,一个for-of循环会很好地完成任务:

function countHashtagsAndMentions(str) {
  let hashtags = 0;
  let mentions = 0;
  for (const ch of str) {
    if (ch === "#") {
      ++hashtags;
    } else if (ch === "@") {
      ++mentions;
    }
  }
  return {hashtags, mentions};
}
let str = "So excited to start  @coding on Monday! #learntocode #codingbootcamp";
console.log(countHashtagsAndMentions(str));

那是因为在ES2015+中,字符串是可迭代的。for-of循环隐式地使用字符串的迭代器来遍历其字符。因此,在循环内部,ch是字符串中的每个字符。请注意,与str.split()不同,字符串迭代器不会将需要代理对(如大多数表情符号)的字符的两个半部分分开,这通常是您想要的。
for (const ch of str) {
    // ...
}

实际上等同于

let it = str[Symbol.iterator]();
let rec;
while (!(rec = it.next()).done) {
    const ch = rec.value;
    // ...
}

但是不包括itrec变量。


或者,您可以使用正则表达式的replace方法替换除要计数的字符以外的所有字符。这听起来可能更耗费资源,但这是JavaScript引擎可以优化的操作:

function countHashtagsAndMentions(str) {
  return {
    hashtags: str.replace(/[^#]/g, "").length,
    mentions: str.replace(/[^@]/g, "").length
  };
}
let str = "So excited to start  @coding on Monday! #learntocode #codingbootcamp";
console.log(countHashtagsAndMentions(str));

你使用哪种方法可能部分取决于字符串的长度。 replace 选项很短,但需要两次遍历字符串。


谢谢,这个完美地解决了我的问题。我有一个关于 for (const ch of str) 的问题。你能解释一下它是如何工作的吗?我从未使用过这样的 for 循环。 - Geo
@GeorgiaLumley - 我更新了答案的一部分,并提供了一些进一步阅读的链接。愉快编码! - T.J. Crowder
1
非常感谢您。 - Geo

0
您可以使用一个对象进行检查和计数。

function countHashtagsAndMentions(str) {
    var result = { '#': 0, '@': 0 },
        i;

    for (i = 0; i < str.length; i++) {
        if (str[i] in result) ++result[str[i]];
    }
    return result;
}

var str = "So excited to start  @coding on Monday! #learntocode #codingbootcamp";

console.log(countHashtagsAndMentions(str));


0
使用 Array#reduce。

const message = "So excited to start @coding on Monday! #learntocode #codingbootcamp"

const res = message.split("").reduce((acc,cur)=>{
  
  if('#@'.includes(cur)){
    const key = cur === '#' ? 'hashtags' : 'mentions';
    acc[key] = acc[key] + 1;

  }
  
  return acc;
}, {mentions: 0, hashtags: 0})

console.log(res);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接