每日的知识积累,包括 1 个 Ts 类型体操,两个 Leetcode 算法题,三个前端八股文题,四个英语表达积累。
1. 一个类型体操
Flatten
在这个挑战中,你需要写一个接受数组的类型,并且返回扁平化的数组类型。
例如:
type flatten = Flatten<[1, 2, [3, 4], [[[5]]]]>; // [1, 2, 3, 4, 5]
分析
这个是数组的遍历,基本上和字符串遍历是一样的吧,注意出口值。
尝试写出
type Flatten<T extends unknown[]> = T extends [infer F, ...infer R]
? F extends any[]
? [...Flatten<F>, ...Flatten<R>]
: [F, ...Flatten<R>]
: T;
测试用例
type flatten = Flatten<[1, 2, [3, 4], [[[5]]]]>; // [1, 2, 3, 4, 5]
参考答案
type Flatten<T extends any[]> = T extends [infer L, ...infer R]
? [...(L extends any[] ? Flatten<L> : [L]), ...Flatten<R>]
: [];
经验总结
- 参考答案中的:
...(L extends any[] ? Flatten<L> : [L])
写的非常的好。这表明,在 扩展运算符对于三目运算具有分配性。
- 由于
T extends unknown[],所以T extends [infer L, ...infer R]的出口是T = []的时候,而不是T["length"] === 1的时候。
type Flatten<T extends any[]> = T extends [infer L, ...infer R] ? L : T;
type C = Flatten<[1]>; // type C = 1
2. 两个 Leetcode 题目
刷题的顺序参考这篇文章 LeeCode 刷题顺序
2.1 [520] 检测大写字母
我们定义,在以下情况时,单词的大写用法是正确的:
全部字母都是大写,比如 "USA" 。
单词中所有字母都不是大写,比如 "leetcode" 。
如果单词不只含有一个字母,只有首字母大写, 比如 "Google" 。
给你一个字符串 word 。如果大写用法正确,返回 true ;否则,返回 false 。
示例 1:
输入:word = "USA"
输出:true
示例 2:
输入:word = "FlaG"
输出:false
提示:
1 <= word.length <= 100
word 由小写和大写英文字母组成
尝试实现:
/**
* @param {string} word
* @return {boolean}
*/
var detectCapitalUse = function (word) {
const n = word.length;
if (n === 1) return true;
if (n === 2) {
// aA
if (word.charCodeAt(0) >= 97 && word.charCodeAt(1) <= 90) {
return false;
} else {
return true;
}
}
const f = word.charCodeAt(0);
const s = word.charCodeAt(1);
if (f >= 97 && s <= 90) return false;
let cls;
if (f <= 90 && s <= 90) cls = 1;
if (f <= 90 && s >= 97) cls = 2;
if (f >= 97 && s >= 97) cls = 3;
for (let i = 2; i < n; i++) {
const cur = word.charCodeAt(i);
if (cls === 1 && cur >= 97) return false;
if (cls === 2 || cls === 3) {
if (cur <= 90) {
return false;
}
}
}
return true;
};
我的思路:
- 如果只有一个字符,直接返回 true
- 如果有两个字符,除了 aA 这种返回 false 其余返回 true
- 三个以上的字符,设置 cls 然后检测前两个字符,AA cls=1 Aa cls=2 aa cls=3
- 从第三个开始遍历, cls 为 1 的时候,剩下字符中出现一个小写则返回 false;
- cls 为 2,3 的时候,剩下字符中出现一个大写则返回 false;
- 遍历完成则返回 true
得分结果: 70.73% 46.45%
总结提升:
- 当一个字符的 code 大于等于 97 为小写;小于等于 90 为大写。需要牢记!
65-9097-122
2.2 [125] 验证回文串
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
示例 1:
输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。
示例 2:
输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。
示例 3:
输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。
提示:
1 <= s.length <= 2 * 105
s 仅由可打印的 ASCII 字符组成
尝试完成:
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function (s) {
let i = 0;
let j = s.length - 1;
while (j > i) {
let p = s.charCodeAt(i);
if (p >= 48 && p <= 57) {
} else {
if (p < 97) {
p += 32;
}
if (p < 97 || p > 122) {
i += 1;
continue;
}
}
let q = s.charCodeAt(j);
if (q >= 48 && q <= 57) {
} else {
if (q < 97) {
q += 32;
}
if (q < 97 || q > 122) {
j -= 1;
continue;
}
}
if (p !== q) return false;
i++;
j--;
}
return true;
};
我的思路:
- 题目虽然不难,但是想要使用一遍遍历就通过却是也是有点难度的
- 采用双指针方法:i j
- 由于有非字符以及大小写的问题,所以对于每一个字符增加预先校验的步骤
- 使用 while 更加合适
- 这里扫盲一个 【字符数字】 的概念
得分结果: 84.85% 99.95%
总结提升:
- 当一个字符的 code 大于等于 97 为小写;小于等于 90 为大写。需要牢记!一个字符数字,即 '0' - '9' 的 code 是 48 - 57.
- 在 js 中
if(3 < q < 9)是非法的!不要这样写!
3. 三个前端题目
- 实现 Array.prototype.every 基本上和 some 的实现过程相同,不同之处仅仅在于什么时候返回 true 以及什么时候返回 false
function myEvery(test) {
if (!Array.isArray(this)) throw new Error("must be called by array");
const _stack = [...this];
if (_stack.length === 0) return false;
while (_stack.length) {
const _value = _stack.pop();
if (!test(_value, _stack.length - 1, _stack)) return false;
}
return true;
}
- 实现 Array.prototype.find 和 some 以及 every 没有什么本质上的区别,同样也是经过检测函数之后的返回值有所变化
function myFind(test) {
if (!Array.isArray(this)) throw new Error("must be called by array");
const _stack = [...this];
while (_stack.length) {
const _value = _stack.pop();
if (test(_value, _stack.length - 1, _stack)) return _value;
}
return undefined;
}
- 实现 Array.prototype.findIndex 仅仅和 find 的返回值有所差别
function myFindIndex(test) {
if (!Array.isArray(this)) throw new Error("must be called by array");
const _stack = [...this];
while (_stack.length) {
const _value = _stack.pop();
if (test(_value, _stack.length - 1, _stack)) return _stack.length - 1;
}
return -1;
}
4.四句英语积累
- no wonder -- [no wonder] that you don't naps.
- time goes fast -- [time goes fast] when you are a wake.
- time is up -- how time files, already [break time is up].
- is not so right --
second himhere is not so right.