最近对函数式编程做了一些了解,这段时间会对 Lodash, Ramda 以及 javascript 基本构造函数的属性做一些整理。在代码中我会使用 typescript 来明确数据类型, 并且会使用 es6,7 的语法。

本文章包含 Lodash String 方法和 javascript String

Lodash String

这里仅分析工具函数的实现方式,以逻辑简洁为主,并且在 Lodash String 中穿插 js String 方法。

Upper Case and Lower Case

1
2
3
4
5
6
7
function toLower(str: string): string {
return str.toLowerCase();
}
function toUpper(str: string): string {
return str.toUpperCase();
}

基本字符串大小写转换,返回新的被转换后的字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const asciiWords = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
const unicodeWords = /[A-Z\xc0-\xd6\xd8-\xde]?[a-z\xdf-\xf6\xf8-\xff]+(?=[\xac\xb1\xd7\xf7\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xbf \t\x0b\f\xa0\n\r]|[A-Z\xc0-\xd6\xd8-\xde]|$)|(?:[A-Z\xc0-\xd6\xd8-\xde])+(?=[\xac\xb1\xd7\xf7\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\xbf \t\x0b\f\xa0\n\r]|[A-Z\xc0-\xd6\xd8-\xde](?:[a-z\xdf-\xf6\xf8-\xff])|$)|[A-Z\xc0-\xd6\xd8-\xde]?(?:[a-z\xdf-\xf6\xf8-\xff])+|[A-Z\xc0-\xd6\xd8-\xde]+|\d+/g;
const hasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
function words(str: string): string[] {
return (
str && str.match(
hasUnicodeWord.test(str) ? unicodeWords : asciiWords
)
) || [];
}
function mapWords (
str: string,
wordMapFn: (word: string, i: number) => string | undefined,
join: string = ''
): string {
return words(str).map(wordMapFn).join(join);
}

words: 将按正则转换为数组。(更加字符类型匹配不同的正则, 这里主要参考 hasUnicodeWord 即可)。
mapWords: 将 words 转换为的数组使用 map 遍历处理,之后使用字符连接为字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
function capitalize(str: string): string {
return str[0].toUpperCase() + str.slice(1);
}
function camelCase(str: string): string {
return mapWords(str, (w, i) => {
return i === 0 ? toLwoer(w) : capitalize(toLower(w));
});
}
function kebabCase(str: string): string {
return mapWords(str, toLower, '-')
}

以逻辑为主,具体的执行速度自行使用 benchmark 测试。

这里可以使用 Curry Function 让函数看起来更直观。

1
2
3
4
5
6
7
8
9
10
11
12
13
function curry(fn, a = []) {
return (...p) => (
o => o.length >= fn.length ? fn(...o) : curry(fn, o)
)(
[...a, ...p]
);
}
function caseStr (casing: string, str: string): string {
return mapWords(str, lowerCase, casing);
}
const kebabCase = curry(caseStr)('-');

Find

这里 Lodash 没有想过的查询,仅介绍 js 的 String。同样以逻辑为主。

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
26
27
28
29
30
31
32
33
34
35
function strFindOfIndex(str: string, index: number = 0): string {
// return str.charAt(index);
return str[index];
}
function strFindOfChar(
str: string,
char: string = '',
start: number = 0
): number {
return str.indexOf(char, start);
}
function strSearchOfChar(
str: string,
rgx: RegExp
): number {
return str.search(RegExp);
}
function strIncludes(
str: string,
char: string,
start: number = 0
): boolean {
return str.includes(char, start);
}
function startWith(
str: string,
char: string,
start: number = 0
): boolean {
return str.startWith(char, start);
}

根据位置(index)查找,根据字符匹配查找,根据正则匹配查找。

Replace

需要用到查找,找到之后进行替换等操作。

1
2
3
4
5
6
7
function strReplace(
str: string,
search: string | RegExp,
replace: string | (match: string, ...pN) => string
): string {
return str.replace(search, replace)
}

replace 可以使用 正则匹配模板,在应对复杂的情况下很强大。MDN Replace

Lodash String 的其他方法 js String 方法均有实现。

Reference