JS压缩字符串-解决无界动态路由标签唯一的需求

项目场景:

使用无界集成微应用时,子应用中打开动态路由,需要发送给主应用,由主应用打开新的页签,但因为是动态路由,没有子应用的对应路由(url),因此需要随机生成一个id


问题描述及原因:

随机id的生成很随机,这里就不说了。这样导致了一个问题,打开同一个动态路由,导致了每次点击,都会随机生成一个新的id,都会重新打开一个新的页签


解决方案:

修改一下id的生成方法

子应用告诉主应用打开动态路由,肯定是要传过来url的。

最简单的方法就是把id设置成url。但是路径就很长很丑

于是在网上找一下有没有可以压缩字符串的算法,即保证准确性,又使得长度美观

说到字符串编码,首先想到了base64编码这种,但是长度没法满足。
查了查网上资料,也没有合适的解决办法,一筹莫展的时候,看到了leetcode的字符串压缩的问题,
开拓了思路:

  1. 路由url转成大写的字符:这一步是为了限制长度,
  2. 找出路由26个英文字母及&字符串分别出现了几次
  3. 将出现的字符以及次数拼接成字符串,用这个字符串来作为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咋整,还得改造一下

将数字的情况也计算出来,但是就不计算次数了,算累加

你可能感兴趣的:(JS,javascript,前端,算法)