项目场景:
使用无界集成微应用时,子应用中打开动态路由,需要发送给主应用,由主应用打开新的页签,但因为是动态路由,没有子应用的对应路由(url),因此需要随机生成一个id。
问题描述及原因:
随机id的生成很随机,这里就不说了。这样导致了一个问题,打开同一个动态路由,导致了每次点击,都会随机生成一个新的id,都会重新打开一个新的页签。
解决方案:
修改一下id的生成方法
子应用告诉主应用打开动态路由,肯定是要传过来url的。
最简单的方法就是把id设置成url。但是路径就很长很丑。
于是在网上找一下有没有可以压缩字符串的算法,即保证准确性,又使得长度美观
说到字符串编码,首先想到了base64编码这种,但是长度没法满足。
查了查网上资料,也没有合适的解决办法,一筹莫展的时候,看到了leetcode的字符串压缩的问题,
开拓了思路:
- 路由url转成大写的字符:这一步是为了限制长度,
- 找出路由26个英文字母及&字符串分别出现了几次
- 将出现的字符以及次数拼接成字符串,用这个字符串来作为id
感觉这种不会出现重复的情况了吧。多巧的路径才能让出现的字符数量顺序都相等
代码
/**
* @description: 子应用向门户发消息打开新页面(动态路由)的的menuId。之前是用的uuid,导致打开同一个页面,会生成两个页签。换种生成方式,不打开新的,切换到已打开的。
* @param {string} S 方法逻辑:参数(其实就是子应用要打开的路由url)大写化-》找出A-Z及&有几个,来组成url
* @return {*}
*/
export const compress = (S: string) => {
const strUpper = S.toLocaleUpperCase();
const isPush = (s: string) => {
const arr: string[] = [
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'S',
'Y',
'Z',
'&',
];
return arr.indexOf(s) > -1;
};
let str = '';
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < strUpper.length; i++) {
const element = strUpper[i];
if (isPush(element)) {
str = str + element;
}
}
let result = '';
const ObjMap = new Map<string, number>();
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < str.length; i++) {
const element = str[i];
if (ObjMap.has(element)) {
ObjMap.set(element, ObjMap.get(element)! + 1);
} else {
ObjMap.set(element, 1);
}
}
for (const [key, value] of ObjMap as any) {
result = result + `${key}${value}`;
}
return result;
};
突然想到万一路由就最后一个参数的value时number咋整
,还得改造一下
将数字的情况也计算出来,但是就不计算次数了,算累加