如何根据输入单词按规则生成唯一编码并通过API完成校验
唯一编码生成实现方案
原有代码问题
- 逻辑错误:第一段代码会对所有单词截取相同长度的字符,不符合「仅第一个单词延长截取长度、其余单词固定取首字母」的规则;且
res变量未初始化,拼接时会自带undefined前缀,编码结果错误 - 功能不全:第二段代码仅实现了固定长度的编码生成,没有冲突后的自动延长逻辑,也没有循环校验直到获取唯一编码的流程
- 异步处理缺失:未针对API的异步返回做流程控制,无法按顺序执行生成→校验→重试的循环逻辑
实现逻辑说明
严格遵循需求规则开发:
- 输入支持1-4个单词,自动过滤多余空格
- 编码生成逻辑:
- 初始截取长度
count=1,第一个单词取前count个字符,其余所有单词固定取首字母拼接 - 调用API校验编码是否已存在,不存在则直接返回可用编码
- 已存在则
count+1重新生成编码校验,直到第一个单词全部截取完毕 - 可选兜底逻辑:第一个单词截取完毕仍有冲突时,拼接数字后缀重试
- 初始截取长度
代码实现(适配Angular技术栈)
方案1:基于RxJS实现(推荐)
利用RxJS expand操作符处理异步递归校验,符合Angular响应式编程习惯:
import { EMPTY, expand } from 'rxjs'; generateUniqueCode(): void { const inputVal = this.userForm.get("name").value?.trim(); if (!inputVal) return; // 拆分单词,过滤空字符串(适配多个连续空格的场景) const wordArr = inputVal.split(" ").filter(word => word.length > 0); if (wordArr.length > 4) { console.error("仅支持最多4个单词的输入"); return; } const firstWord = wordArr[0]; const maxCutLength = firstWord.length; let currentCutLength = 1; // 编码生成工具方法 const buildCode = (cutLength: number): string => { let code = firstWord.substring(0, cutLength); // 其余单词全部取首字母拼接 for (let i = 1; i < wordArr.length; i++) { code += wordArr[i][0]; } return code; } // 循环校验逻辑 this.restApi.validateCode(buildCode(currentCutLength)).pipe( expand((isExist: boolean) => { // 编码不存在,可用,终止循环 if (!isExist) { const finalCode = buildCode(currentCutLength); console.log("生成唯一编码:", finalCode); // 可直接赋值给表单字段 // this.userForm.get('uniqueCode').setValue(finalCode); return EMPTY; } currentCutLength++; // 第一个单词已截取完毕,进入兜底逻辑可自行扩展 if (currentCutLength > maxCutLength) { console.error("已到最大截取长度,可扩展数字后缀兜底逻辑"); return EMPTY; } // 继续校验下一个生成的编码 return this.restApi.validateCode(buildCode(currentCutLength)); }) ).subscribe(); }
方案2:基于async/await实现
更易理解的同步写法,需要先将API返回的Observable转成Promise:
// 封装校验API为Promise private validateCode(code: string): Promise<boolean> { return this.restApi.validateCode(code).toPromise(); } async generateUniqueCode(): Promise<void> { const inputVal = this.userForm.get("name").value?.trim(); if (!inputVal) return; const wordArr = inputVal.split(" ").filter(word => word.length > 0); if (wordArr.length > 4) { console.error("仅支持最多4个单词的输入"); return; } const firstWord = wordArr[0]; const maxCutLength = firstWord.length; let currentCutLength = 1; // 按规则生成编码并校验 while (currentCutLength <= maxCutLength) { let code = firstWord.substring(0, currentCutLength); for (let i = 1; i < wordArr.length; i++) { code += wordArr[i][0]; } const isExist = await this.validateCode(code); if (!isExist) { console.log("生成唯一编码:", code); // this.userForm.get('uniqueCode').setValue(code); return; } currentCutLength++; } // 兜底逻辑:截取完第一个单词仍冲突时,拼接数字后缀重试 let suffix = 1; const prefix = `${firstWord}${wordArr.slice(1).map(w => w[0]).join('')}`; while(true) { const finalCode = `${prefix}${suffix}`; const isExist = await this.validateCode(finalCode); if (!isExist) { console.log("生成兜底唯一编码:", finalCode); // this.userForm.get('uniqueCode').setValue(finalCode); return; } suffix++; } }
内容的提问来源于stack exchange,提问作者A Coder
相关产品推荐
相关产品推荐

