[codewars 译解注] Isograms
题目简介
- 原题地址: codewars
- 题目等级: 7 kyu
译
isogram[1] 是指一个没有重复字母的词, 无论连续还是非连续. 实现一个函数, 该函数确定只包含字母的字符串是否是 isogram. 假设空字符串是 isogram. 忽略字母大小写.
isIsogram( "Dermatoglyphics" ) == true
isIsogram( "aba" ) == false
isIsogram( "moOse" ) == false // -- 忽略字母大小写
1
2
3
2
3
解注
Part 1
首先来看看我的实现
function isIsogram(str){
// 这里用于 "假设空字符串是 isogram"
if (!str) return true;
// "忽略字母大小写", 因此将其全部转为小写
str = str.toLocaleLowerCase();
/**
* 以下为核心部分
* 1. 遍历字符串的每个字符
* 2. 将当前字符其存入栈中
* 3. 在存入栈前, 判断栈中是否存在该字符
*/
const tmp = [];
for (let index = 0; index < str.length; index++) {
const element = str[index];
if (tmp.indexOf(element) === -1) {
tmp.push(element);
} else {
return false;
}
}
return true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Part 2
有没有更巧妙的方式呢, 来看以下这个 Best Practices 的第一名[2]
function isIsogram(str){
return !/(\w).*\1/i.test(str)
}
1
2
3
2
3
用到了我暂时还不擅长的正则表达式, 那我们就来研究一下吧
/.../i
表达式的结尾处的不区分大小写 i 标记指定不区分大小写.\w
匹配字母或数字或下划线或汉字 等价于[^A-Za-z0-9_]
.a.*b
它将会匹配最长的以a开始,以b结束的字符串.\1
指定第一个子匹配项.
因此就是匹配两个相同字符之间的字符串.
Part 3
既然正则不熟, 我们再找找. 看, 这个:
function isIsogram(str){
return new Set(str.toUpperCase()).size == str.length;
}
1
2
3
2
3
是使用了 es6+ 中出现的 Set
.
Set
[3] 对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。
拍手称赞.
总结
这是一道很简单的题, 前端初学者基本上都能像我一样写出答案, 但是看过别人更巧妙的解答, 你有学到什么吗?
isograms: 直译为 "等值线图". 在维基百科中明确其含义为与本题目一致, 用于地理和制图术语时可以参阅 contour line. ↩︎
排名截止到当前文章编辑时间, 后续可能会发生变更. ↩︎
查看 MDN 中 Set 的文档 ↩︎