我是编码新手,有人问我这个问题。
这个问题是;
创建一个函数,该函数接收一个字符串,该字符串将包含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 });
});
});
有人对如何使我的代码工作有任何建议吗?
一个简单的循环就可以做到这一点。由于您使用的是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;
// ...
}
但没有CCD_ 5和CCD_。
或者,可以将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
选项很好,很短,但确实会遍历字符串两次。
您可以使用对象进行检查和计数。
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));
使用数组#减少
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);