Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 优化自定义 dict 的逻辑 #239

Merged
merged 1 commit into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 70 additions & 8 deletions lib/core/dict/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Priority, Probability } from "@/common/constant";
import { Pattern, acTree } from "@/common/segmentit";
import { getStringLength } from "@/common/utils";
import DICT1 from "@/data/dict1";

const DefaultName = Symbol("default");

type DICT = {
[key: string]:
Expand All @@ -9,34 +13,92 @@ type DICT = {
| [string, number, string]; // [拼音, 词频概率, 词性]
};

export function addDict(dict: DICT | {}, name?: string) {
type DictOptions = {
name?: string;
dict1?: "add" | "replace" | "ignore";
};

const originDictMap = new Map<string | Symbol, { [word: string]: string }>();

export function addDict(dict: DICT | {}, options?: string | DictOptions) {
const patterns: Pattern[] = [];
// string 类型时:options 为 name()
const name = typeof options === "object" ? options.name : options;
const dictName = name || DefaultName;
const dict1Handle = (options as DictOptions)?.dict1 || "add";
for (let key in dict as DICT) {
const value = (dict as DICT)[key];
const pinyin = Array.isArray(value) ? value[0] : value;
if (getStringLength(key) === 1) {
addToOriginDict(
dictName,
key,
pinyin,
dict1Handle
);
}
if (Array.isArray(value)) {
patterns.push({
zh: key,
pinyin: value[0],
probability: typeof value[1] === "number" ? value[1] : Probability.DICT * key.length * key.length,
pinyin,
probability:
typeof value[1] === "number"
? value[1]
: Probability.DICT * key.length * key.length,
length: key.length,
priority: Priority.Normal,
dict: name || Symbol(""),
dict: dictName,
pos: typeof value[2] === "string" ? value[2] : "",
});
} else {
patterns.push({
zh: key,
pinyin: value,
pinyin,
probability: Probability.DICT * key.length * key.length,
length: key.length,
priority: Priority.Normal,
dict: name || Symbol(""),
dict: dictName,
});
}
}
acTree.build(patterns);
}

export function removeDict(dictName: string) {
acTree.removeDict(dictName);
export function removeDict(dictName?: string) {
acTree.removeDict(dictName || DefaultName);
removeOriginDict(dictName || DefaultName);
}

function addToOriginDict(
dict: string | Symbol,
key: string,
pinyin: string,
handle: "add" | "replace" | "ignore" = "add"
) {
if (!originDictMap.get(dict)) {
originDictMap.set(dict, {})
}
const originDict = originDictMap.get(dict)!;
const code = key.charCodeAt(0);
if (!originDict[key]) {
originDict[key] = DICT1[code] as string;
}
if (handle === "add") {
if (DICT1[code] && !DICT1[code].split(' ').includes(pinyin)) {
DICT1[code] += ` ${pinyin}`;
} else if (!DICT1[code]) {
DICT1[code] = pinyin;
}
} else if (handle === "replace") {
DICT1[code] = pinyin;
}
}

function removeOriginDict(dict: string | Symbol) {
const originDict = originDictMap.get(dict) || {};
for (let key in originDict) {
const code = key.charCodeAt(0);
DICT1[code] = originDict[key];
delete originDict[key];
}
}
40 changes: 40 additions & 0 deletions test/dict.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,44 @@ describe("addDict", () => {
const result = pinyin("汉语拼音");
expect(result).to.be.equal("hàn yǔ pīn yīn");
});

it("[addDict]dict handle add", () => {
const stringDict = {
汉: ['yīn']
}
addDict(stringDict, { name: "handle-add", dict1: 'add' });
const result = pinyin("汉", { multiple: true });
expect(result).to.be.equal("hàn yīn");
removeDict('handle-add');
});

it("[addDict]dict handle replace", () => {
const stringDict = {
汉: ['yīn']
}
addDict(stringDict, { name: "handle-replace", dict1: 'replace' });
const result = pinyin("汉", { multiple: true });
expect(result).to.be.equal("yīn");
removeDict('handle-replace');
});

it("[addDict]undefined dict", () => {
const stringDict = {
䃜: 'yī'
}
addDict(stringDict, { name: "handle-new" });
const result = pinyin("䃜");
expect(result).to.be.equal("yī");
removeDict('handle-new');
});

it("[addDict]unnamed dict", () => {
const stringDict = {
䃜: 'yī'
}
addDict(stringDict);
const result = pinyin("䃜");
expect(result).to.be.equal("yī");
removeDict();
});
});
8 changes: 6 additions & 2 deletions types/core/dict/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
type DICT = {
[key: string]: string | [string] | [string, number] | [string, number, string];
};
export declare function addDict(dict: DICT | {}, name?: string): void;
export declare function removeDict(dictName: string): void;
type DictOptions = {
name?: string;
dict1?: "add" | "replace" | "ignore";
};
export declare function addDict(dict: DICT | {}, options?: string | DictOptions): void;
export declare function removeDict(dictName?: string): void;
export {};
Loading