先让我们想一个业务模型吧,身为一名ikun,我们想成为一名合格的偶像练习生,需要会唱跳rap篮球,缺一不可,业务模型来点有创意的话,唱=》跳=》rap=》篮球=》成为练习生,如果不会'跳',那么流程就不往下执行了。
首先,先来最low的写法:
import * as _ from 'lodash';
const skill: Array<string> = ['sing', 'dance', 'rap', 'basketball'];
const find = (arr: string[], str: string) => {
return _.find(arr, (v: string): boolean => {
if (v === str) {
return true;
} else {
return false;
}
});
};
const allSuccessStr = `I'm kunkun`;
const successStr = (str: string) => `i can ${str}`;
const failStr = (str: string) =>
`I'm not an idol trainee, because i can not ${str}`;
if (find(skill, 'sing')) {
console.log(successStr('sing'));
if (find(skill, 'dance')) {
console.log(successStr('dance'));
if (find(skill, 'rap')) {
console.log(successStr('rap'));
if (find(skill, 'basketball')) {
console.log(successStr('basketball'));
console.log(allSuccessStr);
} else {
console.log(failStr('basketball'));
}
} else {
console.log(failStr('rap'));
}
} else {
console.log(failStr('dance'));
}
} else {
console.log(failStr('sing'));
}
可以看到,嵌套特别特别多,代码实在是过于臃肿,可读性特别差,我们要把嵌套扁平化,(在很深的树形结构,也可以讲结构扁平化,这样效率会成倍增加)
其次,这是普通的写法:
if (skill['sing']) {
console.log(successStr('sing'));
} else {
console.log(failStr('sing'));
return;
}
if (skill['dance1']) {
console.log(successStr('dance'));
} else {
console.log(failStr('dance'));
return;
}
if (skill['rap']) {
console.log(successStr('rap'));
} else {
console.log(failStr('rap'));
return;
}
if (skill['basketball']) {
console.log(successStr('basketball'));
} else {
console.log(failStr('basketball'));
return;
}
之后,这是再次优化的最佳写法,我们把数组改为对象,这样时间复杂度就是1了:
interface Skill {
sing: boolean;
dance: boolean;
rap: boolean;
basketball: boolean;
[propName: string]: boolean;
}
const allSuccessStr = () => console.log(`I'm kunkun`);
const successStr = (str: string) => `i can ${str}`;
const failStr = (str: string) =>
`I'm not an idol trainee, because i can not ${str}`;
const skill: Skill = {
sing: true,
dance: true,
rap: true,
basketball: true,
};
const isSkill = (v: string): Boolean => {
if (skill[v]) {
successStr(v);
return true;
} else {
failStr(v);
return false;
}
};
isSkill('sing') &&
isSkill('dance') &&
isSkill('rap') &&
isSkill('basketball') &&
allSuccessStr();
最后,放大招,Rxjs直接秒杀!
interface Skill {
sing: boolean;
dance: boolean;
rap: boolean;
basketball: boolean;
[propName: string]: boolean;
}
const skill: Skill = {
sing: true,
dance: true,
rap: true,
basketball: true,
};
const source = of('sing', 'dance', 'rap', 'basketball')
.pipe(takeWhile((v) => skill[v] == true))
.subscribe(
(val) => console.log(val),
() => {},
() => console.log('done')
);