最近有一个挺有意思的小需求,有一组词的分类需要按照拼音归类且排序,基本类似于电话薄按照英文字母排序的功能。

假如后端给出的数据是

# 原始数据

[
  {
    "tag": "感动",
    "pinyin": "gan dong"
  },
  {
    "tag": "爱国",
    "pinyin": "ai guo"
  },
  {
    "tag": "感动中国",
    "pinyin": "gan dong zhong guo"
  },
  {
    "tag": "富强",
    "pinyin": "fu qiang"
  }
]

最终需要将数据转为

# 目标数据

[
  {
    "letter": "a",
    "data": ["爱国"]
  },
  {
    "letter": "f",
    "data": ["富强"]
  },
  {
    "letter": "g",
    "data": ["感动", "感动中国"]
  }
]

实现思路,可以借助 Map 的属性,先查看当前的数据是否已经被推入 data 中,如果已经被推入则需要更新,否则直接 pushdata 中,并且跟新 Map 的状态。

# 实现

type tagsTypes = 'tag' | 'pinyin'

interface IResult {
  letter: string;
  data: string[];
}

const pySegSort = (arr: Record<tagsTypes, string>[]) => {
  let wordsMap: Map<string, boolean> = new Map();
  let moreWords: IResult[] = [];
  arr.forEach((item) => {
    // 取首字母
    const initials = item.pinyin.charAt(0).toLowerCase();
    // 若Map中不存在,直接push,并且更新状态
    if (!wordsMap.has(initials)) {
      moreWords.push({
        letter: initials,
        data: [item.tag],
      });
      wordsMap.set(initials, true);
    } else {
      // 否则就寻找去拼接
      moreWords.forEach((e) => {
        if (e.letter === initials) {
          e.data = [...new Set([...e.data, item.tag])];
        }
      });
    }
  });
  // 最终取数据的首字母的ASCII码排序
  return moreWords.sort(
    (a, b) => a.letter.charCodeAt(0) - b.letter.charCodeAt(0)
  );
};
最后更新: 2/12/2023, 7:42:22 AM