updated js优化

This commit is contained in:
mumuy 2025-04-12 12:35:28 +08:00
parent 5de00bca62
commit a706d387cc
11 changed files with 166 additions and 203 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,22 +5,23 @@ import _input from './data/input.js';
import _sort from './data/sort.js';
import {modeData} from './mode.js';
let _hash = Object.assign({},modeData);
for(let key in _input){
_hash[key] = (_hash[key]||[]).concat(_input[key]);
}
for(let key in _sort){
_hash[key] = (_hash[key]||[]).concat(_sort[key]);
function mergeValues(target, source) {
Object.entries(source).forEach(([key, value]) => {
target[key] = (target[key] || []).concat(value);
});
return target;
}
let _hash = mergeValues({...modeData }, _input);
_hash = mergeValues(_hash, _sort);
let cacheData = {};
for(let key in _hash){
_hash[key].forEach(function(name){
if(typeof cacheData[name]=='undefined'){
Object.entries(_hash).forEach(([key, names]) => {
names.forEach((name) => {
if (!cacheData[name]) {
cacheData[name] = [];
}
cacheData[name].push(key);
});
}
});
export {cacheData};
export {cacheData};

View File

@ -44,12 +44,11 @@ export function reverseId(id,sex){
sex = 0;
}
}
let doing = function(sex){
let sid = (','+sex+','+id).replace(/,[fhs]|,[olx]b/g,',1').replace(/,[mwd]|,[olx]s/g,',0');
sid = sid.substring(0,sid.length-2);
let sid_arr = sid.split(',').reverse();
let r_id = id.split(',').reverse().map((id,i)=>hash[id][sid_arr[i]]).join(',');
let gen = getGenById(r_id);
const doing = function(sex){
const sid = (','+sex+','+id).replace(/,[fhs]|,[olx]b/g,',1').replace(/,[mwd]|,[olx]s/g,',0');
const sid_arr = sid.substring(0,sid.length-2).split(',').reverse();
const r_id = id.split(',').reverse().map((id,i)=>hash[id][sid_arr[i]]).join(',');
const gen = getGenById(r_id);
return r_id + (gen?'':age);
};
if(sex<0){
@ -61,19 +60,19 @@ export function reverseId(id,sex){
// ID列表去重
export function filterId(arr){
let sameList = arr.filter(item=>item==item.replace(/[ol](?=[s|b])/g,'x').replace(/&[ol]/,''));
return arr.filter(item=>{
let temp = item.replace(/[ol](?=[s|b])/g,'x').replace(/&[ol]/,'');
const sameList = arr.filter(item => item === item.replace(/[ol](?=[s|b])/g,'x').replace(/&[ol]/,''));
return arr.filter(item => {
const temp = item.replace(/[ol](?=[s|b])/g,'x').replace(/&[ol]/,'');
return sameList.includes(item)||item!=temp&&!sameList.includes(temp);
}).filter((item,idx,arr) => arr.indexOf(item) === idx);
};
// 通过ID获取世代数
export function getGenById(id){
let gMap = {'f':1,'m':1,'s':-1,'d':-1};
const gMap = {'f':1,'m':1,'s':-1,'d':-1};
let gen = 0;
id.split(',').forEach(function(sub){
let s = sub.replace(/&[ol\d]+/,'');
id.split(',').forEach(sub => {
const s = sub.replace(/&[ol\d]+/,'');
gen += gMap[s]||0;
});
return gen;
@ -82,29 +81,26 @@ export function getGenById(id){
// 通过ID获取关系称呼
export function getItemsById(id){
let items = [];
let getData = function(key){
const getData = function(key){
let ids = [];
let k1 = key.replace(/(,[sd])(,[wh])?$/,'$1&o$2');
let k2 = key.replace(/(,[sd])(,[wh])?$/,'$1&l$2');
const k1 = key.replace(/(,[sd])(,[wh])?$/,'$1&o$2');
const k2 = key.replace(/(,[sd])(,[wh])?$/,'$1&l$2');
if(modeData[k1]&&modeData[k2]){
ids = [k1,k2];
}else if(modeData[key]){
ids = [key];
}
return filterId(ids).map(function(id){
return modeData[id][0];
});
return filterId(ids).map(id => modeData[id][0]);
};
// 对排序进行处理
if(id.match(/&([\d]+)(,[hw])?$/)){
let num = id.match(/&([\d]+)(,[hw])?$/)[1];
let zh = number2zh(num);
const num = id.match(/&([\d]+)(,[hw])?$/)[1];
const zh = number2zh(num);
id = id.replace(/&\d+/g,'');
if(_sort[id]){
let item = _sort[id][0].replace('几',zh);
items.push(item);
items.push(_sort[id][0].replace('几',zh));
}else if(modeData[id]){
let gen = getGenById(id);
const gen = getGenById(id);
let item = '';
if(gen<3&&!id.match(/[hw],/)){
modeData[id].forEach(function(name){
@ -145,13 +141,14 @@ export function getItemsById(id){
};
// 通过ID获取关系链
let data = Object.assign({},modeData,{
'xb':['兄弟'],
'xs':['姐妹']
});
let data = {
...modeData,
'xb': ['兄弟'],
'xs': ['姐妹']
};
export function getChainById(id,sex=-1){
let item = id.split(',').map(function(sign){
let key = sign.replace(/&[ol\d]+/,'');
let item = id.split(',').map(sign => {
const key = sign.replace(/&[ol\d]+/,'');
return data[key][0];
}).join('的');
if(sex>-1&&data[sex+','+id]){
@ -166,26 +163,23 @@ export function getChainById(id,sex=-1){
// 通过ID获取关系合称
export function getPairsById(id1,id2){
id1 = id1.replace(/&\d+/g,'');
id2 = id2.replace(/&\d+/g,'');
const id1_x = id1.replace(/([ol])([bs])/g,'x$2');
const id2_x = id2.replace(/([ol])([bs])/g,'x$2');
const id1_r = id1.replace(/&[ol]/g,'');
const id2_r = id2.replace(/&[ol]/g,'');
let result = [];
let result_x = [];
let result_r = [];
id1 = id1.replace(/&\d+/g,'');
id2 = id2.replace(/&\d+/g,'');
let id1_x = id1.replace(/([ol])([bs])/g,'x$2');
let id2_x = id2.replace(/([ol])([bs])/g,'x$2');
let id1_r = id1.replace(/&[ol]/g,'');
let id2_r = id2.replace(/&[ol]/g,'');
for(let key in _pair){
let selectors = key.split('#');
for(const key in _pair){
const selectors = key.split('#');
if(selectors.length>1){
let list1 = selector2id(selectors[0]);
let list2 = selector2id(selectors[1]);
let list1_r = list1.map(function(selector){
return selector.replace(/&[ol\d]+/,'').replace(/([ol])([bs])/,'x$2');
});
let list2_r = list2.map(function(selector){
return selector.replace(/&[ol\d]+/,'').replace(/([ol])([bs])/,'x$2');
});
const list1 = selector2id(selectors[0]);
const list2 = selector2id(selectors[1]);
const list1_r = list1.map(selector => selector.replace(/&[ol\d]+/,'').replace(/([ol])([bs])/,'x$2'));
const list2_r = list2.map(selector => selector.replace(/&[ol\d]+/,'').replace(/([ol])([bs])/,'x$2'));
if(list1.includes(id1)&&list2.includes(id2)||list1.includes(id2)&&list2.includes(id1)){
result.push(_pair[key][0]);
}
@ -204,4 +198,4 @@ export function getPairsById(id1,id2){
result = result_r;
}
return result;
};
};

View File

@ -8,46 +8,39 @@ import _multipie from './data/multiple.js';
import {expandSelector} from './selector.js';
let _map = Object.assign({},_multipie);
let _map = { ..._multipie };
// 分支 - 前缀处理
let prefixMap = {};
for(let key in _prefix){
const prefixMap = {};
for(const key in _prefix){
prefixMap[key] = {};
for(let selector in _prefix[key]){
for(const selector in _prefix[key]){
expandSelector(selector).forEach(function(s){
prefixMap[key][s] = _prefix[key][selector];
});
}
}
// 分支 - 节点处理
let branchMap = {};
for(let selector in _branch){
const branchMap = {};
for(const selector in _branch){
expandSelector(selector).forEach(function(s){
branchMap[s] = _branch[selector];
});
}
// 分支 - 合并
let getMap = function(prefixMap,branchMap){
let map = {};
for(let key in branchMap){
let tag = key.match(/\{.+?\}/)[0];
let nameList = branchMap[key];
for(let k in prefixMap[tag]){
let prefixList = prefixMap[tag][k];
let newKey = key.replace(tag,k);
let isFilter = ['h,h','w,w','w,h','h,w'].some(pair=>(newKey.includes(pair)));
const getMap = function(prefixMap,branchMap){
const map = {};
for(const key in branchMap){
const tag = key.match(/\{.+?\}/)[0];
const nameList = branchMap[key];
for(const k in prefixMap[tag]){
const prefixList = prefixMap[tag][k];
const newKey = key.replace(tag,k);
const isFilter = ['h,h','w,w','w,h','h,w'].some(pair=>(newKey.includes(pair)));
if(!isFilter){
let newList = [];
prefixList.forEach(function(prefix){
nameList.forEach(function(name){
if(name.includes('?')){
newList.push(name.replace('?',prefix));
}else{
newList.push(prefix+name);
}
});
});
const newList = prefixList.flatMap((prefix) =>
nameList.map((name) => (name.includes('?') ? name.replace('?', prefix) : prefix + name))
);
if(!map[newKey]){
map[newKey] = _map[newKey]||[];
}
@ -57,11 +50,11 @@ let getMap = function(prefixMap,branchMap){
}
return map;
};
_map = Object.assign({},_map,getMap(prefixMap,branchMap));
_map = {..._map,...getMap(prefixMap,branchMap)};
// 主要关系
for(let key in _main){
_map[key] = [].concat(_main[key],_map[key]||[]);
_map[key] = [..._main[key], ...(_map[key] || [])];
}
// 版权彩蛋
@ -72,10 +65,10 @@ const mateMap = {
'w':['妻','内','岳','岳家','丈人'],
'h':['夫','外','公','婆家','婆婆'],
};
let nameSet = new Set(Object.values(_map).flat());
for(let key in _map){
const nameSet = new Set(Object.values(_map).flat());
for(const key in _map){
if(key.match(/^[fm]/)||key.match(/^[olx][bs]$|^[olx][bs],[^mf]/)){ // 只对长辈或者兄弟辈匹配
for(let k in mateMap){
for(const k in mateMap){
let newKey = k+','+key;
if(key.match(/[fm]/)){
let newKey_x = newKey.replace(/,[ol]([sb])(,[wh])?$/,',x$1$2').replace(/(,[sd])&[ol](,[wh])?$/,'$1$2');
@ -86,11 +79,11 @@ for(let key in _map){
if(!_map[newKey]){
_map[newKey] = [];
}
let prefixList = mateMap[k];
let nameList = _map[key];
const prefixList = mateMap[k];
const nameList = _map[key];
prefixList.forEach(function(prefix){
nameList.forEach(function(name){
let newName = prefix+name;
const newName = prefix+name;
if(!nameSet.has(newName)){ // 配偶组合的称呼不得与原有称呼冲突(如:妻舅!=妻子的舅舅;外舅公!=老公的舅公)
_map[newKey].push(newName);
}

View File

@ -4,22 +4,22 @@
import _map from './map.js';
let _mode = {}; // 模式缓存
let modeData = Object.assign({},_map); // 最终数据
let modeData = { ..._map }; // 最终数据
// 设置模式数据
export function setModeData(sign,data){
_mode[sign] = Object.assign(_mode[sign]||{},data);
_mode[sign] = { ...(_mode[sign] || {}), ...data };
};
// 获取模式数据
export function getModeData(sign){
modeData = Object.assign({},_map);
modeData = { ..._map };
if(sign&&_mode[sign]){
for(let key in _mode[sign]){
for(const key in _mode[sign]){
modeData[key] = [].concat(_mode[sign][key],_map[key]||[]);
}
}
return modeData;
};
export {modeData};
export {modeData};

View File

@ -4,8 +4,8 @@
import _expression from './rule/expression.js';
export function getOptions(text){
for(let item of _expression){
let match = text.match(item['exp']);
for(const item of _expression){
const match = text.match(item['exp']);
if(match){
return item['opt'](match);
}

View File

@ -10,7 +10,7 @@ import {reverseId,filterId,getGenById} from './id.js';
import {cacheData} from './cache.js';
// 获得最简
let getOptimal = function(options){
const getOptimal = function(options){
let {
from,
to,
@ -81,18 +81,18 @@ export function getSelectors(str){
str = str.replace(/(伯|叔)+(父|母)?家的?(哥|姐|弟|妹)+/,'堂$3').replace(/(伯|叔)+(父|母)?家的?/,'堂');
str = str.replace(/姨+(爸|父|丈|妈|母)?家的?(哥|姐|弟|妹)+/,'姨$2').replace(/姨+(爸|父|丈|妈|母)?家的?/,'姨');
let lists = str.split('的');
const lists = str.split('的');
let result = [];
let isMatch = true;
while(lists.length){
let name = lists.shift(); //当前匹配词
const name = lists.shift(); //当前匹配词
let items = []; //当前匹配词可能性
let keywords = [name];
const keywords = [name];
let getList = function(name){
// 词义扩展
_replace.forEach(item => {
item['arr'].forEach(word =>{
let name1 = name.replace(item['exp'],word);
const name1 = name.replace(item['exp'],word);
if(name1!=name){
keywords.push(name1);
getList(name1);
@ -100,9 +100,9 @@ export function getSelectors(str){
});
});
// 同义词替换
for(let word in _similar){
let name1 = name.replace(word,_similar[word]);
let name2 = name.replace(_similar[word],word);
for(const word in _similar){
const name1 = name.replace(word,_similar[word]);
const name2 = name.replace(_similar[word],word);
if(name1!=name){
keywords.push(name1);
}
@ -113,19 +113,19 @@ export function getSelectors(str){
};
getList(name);
// 通过关键词找关系
let items_map = [[],[],[]];
const items_map = [[],[],[]];
keywords.forEach(function(name){
name = name.replace(/^[尕幺细满碎晚末尾幼]/,'小');
let match = name.match(/^[大|小]|^[一|二|三|四|五|六|七|八|九|十]+/);
const match = name.match(/^[大|小]|^[一|二|三|四|五|六|七|八|九|十]+/);
if(match){ // 匹配排序
let x_name = name.replace(match[0],'几');
let r_name = name.replace(match[0],'');
let num = zh2number(match[0]);
[x_name,r_name,name].forEach(function(name,index){
let ids = cacheData[name];
const x_name = name.replace(match[0],'几');
const r_name = name.replace(match[0],'');
const num = zh2number(match[0]);
[x_name,r_name,name].forEach((name, index) => {
const ids = cacheData[name];
if(ids&&ids.length){
ids.forEach(function(i){
let id = i.replace(/(,[hw])$/,'&'+num+'$1').replace(/([^hw]+)$/,'$1&'+num);
ids.forEach(i => {
const id = i.replace(/(,[hw])$/,'&'+num+'$1').replace(/([^hw]+)$/,'$1&'+num);
if(!i.match(/^[mf,]+$/)&&!name.match(/^[从世]/)){ // 直系祖辈不参与排序
items_map[index].push(id);
}
@ -146,7 +146,7 @@ export function getSelectors(str){
if(!items.length){
isMatch = false;
}
let res = [];
const res = [];
if(!result.length){
result = [''];
}
@ -168,25 +168,15 @@ export function mergeSelector(param){
sex:my_sex
} = param;
if(my_sex<0){
let to_sex = -1;
let from_sex = -1;
if(from_selector.match(/^,[w1]/)){
from_sex = 1;
}else if(from_selector.match(/^,[h0]/)){
from_sex = 0;
}
if(to_selector.match(/^,[w1]/)){
to_sex = 1;
}else if(to_selector.match(/^,[h0]/)){
to_sex = 0;
}
if(from_sex==-1&&to_sex>-1){
my_sex = to_sex;
}else if(from_sex>-1&&to_sex==-1){
my_sex = from_sex;
}else if(from_sex==to_sex){
my_sex = from_sex;
}else{
const fromSex = from_selector.match(/^,[w1]/) ? 1 : from_selector.match(/^,[h0]/) ? 0 : -1;
const toSex = to_selector.match(/^,[w1]/) ? 1 : to_selector.match(/^,[h0]/) ? 0 : -1;
if (fromSex === -1 && toSex > -1) {
my_sex = toSex;
} else if (fromSex > -1 && toSex === -1) {
my_sex = fromSex;
} else if (fromSex === toSex) {
my_sex = fromSex;
} else {
return [];
}
}
@ -195,9 +185,9 @@ export function mergeSelector(param){
if(!from_ids.length||!to_ids.length){
return [];
}
let result = [];
from_ids.forEach(function(from){
to_ids.forEach(function(to){
const result = [];
from_ids.forEach(from => {
to_ids.forEach(to => {
let sex = my_sex;
let selector = ','+to;
if(selector.match(/,([fhs1](&[ol\d]+)?|[olx]b)(&[ol\d]+)?$/)){
@ -239,15 +229,15 @@ export function mergeSelector(param){
// 扩展选择器
export function expandSelector(selector){
let result = [];
let hash = {};
let getSelector = function(selector){
let s='';
const result = [];
const hash = {};
const getSelector = function(selector){
if(!hash[selector]){
hash[selector] = true;
let s='';
do{
s = selector;
for(let item of _filter){
for(const item of _filter){
// console.log('[filter]',item['exp'],selector);
selector = selector.replace(item['exp'],item['str']);
if(selector.includes('#')){
@ -289,8 +279,6 @@ export function selector2id(selector,sex){
if(selector.match(/,[mwd0](&[ol\d]+)?,w|,[hfs1](&[ol\d]+)?,h/)){ //同志关系去除
return [];
}
let result = expandSelector(selector).map(function(selector){
return selector.replace(/,[01]/,'').substr(1); //去前面逗号和性别信息
});
const result = expandSelector(selector).map(selector => selector.replace(/,[01]/, '').substr(1)); //去前面逗号和性别信息
return filterId(result);
};
};

View File

@ -4,44 +4,39 @@ import {reverseId,getItemsById,getChainById,getPairsById} from './module/id.js';
import {setModeData,getModeData,modeData} from './module/mode.js';
// 对外方法
let relationship = function (parameter){
let relationship = function (parameter) {
if(typeof parameter =='string'){
parameter = getOptions(parameter);
}
let options = Object.assign({
text:'', // 目标对象:目标对象的称谓汉字表达,称谓间用‘的’字分隔
target:'', // 相对对象:相对对象的称谓汉字表达,称谓间用‘的’字分隔,空表示自己
sex:-1, // 本人性别0表示女性,1表示男性
type:'default', // 转换类型:'default'计算称谓,'chain'计算关系链,'pair'计算关系合称
reverse:false, // 称呼方式true对方称呼我,false我称呼对方
mode:'default', // 模式选择使用setMode方法定制不同地区模式在此选择自定义模式
optimal:false // 最短关系:计算两者之间的最短关系
},parameter);
text: '', // 目标对象:目标对象的称谓汉字表达,称谓间用‘的’字分隔
target: '', // 相对对象:相对对象的称谓汉字表达,称谓间用‘的’字分隔,空表示自己
sex: -1, // 本人性别0表示女性,1表示男性
type: 'default', // 转换类型:'default'计算称谓,'chain'计算关系链,'pair'计算关系合称
reverse: false, // 称呼方式true对方称呼我,false我称呼对方
mode: 'default', // 模式选择使用setMode方法定制不同地区模式在此选择自定义模式
optimal: false // 最短关系:计算两者之间的最短关系
}, parameter);
// 切换模式
getModeData(options.mode);
let from_selectors = getSelectors(options.text);
let to_selectors = getSelectors(options.target);
if(!to_selectors.length){
to_selectors = [''];
let fromSelectors = getSelectors(options.text);
let toSelectors = getSelectors(options.target);
if (!toSelectors.length) {
toSelectors = [''];
}
let result = []; //匹配结果
// console.log('[selectors]',from_selectors,to_selectors);
from_selectors.forEach(function(from_selector){
to_selectors.forEach(function(to_selector){
mergeSelector({
from:from_selector,
to:to_selector,
sex:options.sex,
optimal:options.optimal
}).forEach(function(data){
// console.log('[data]',from_selector,to_selector,options.optimal,data);
let ids = data?selector2id(data['selector'],data['sex']):[];
// console.log('[ids]',data['selector'],data['sex'],ids);
ids.forEach(function(id){
const result = fromSelectors.flatMap(fromSelector => {
return toSelectors.flatMap(toSelector => {
return mergeSelector({
from: fromSelector,
to: toSelector,
sex: options.sex,
optimal: options.optimal
}).flatMap(data => {
const ids = data ? selector2id(data['selector'], data['sex']) : [];
return ids.flatMap(id => {
let temps = [id];
let sex = data['sex'];
if(options.reverse){
if (options.reverse) {
temps = reverseId(id,sex);
if(id.match(/([fhs1](&[ol\d]+)?|[olx]b)$/)){
sex = 1;
@ -49,33 +44,25 @@ let relationship = function (parameter){
sex = 0;
}
}
if(options.type=='chain'){
temps.forEach(function(id){
let item = getChainById(id,data['sex']);
if(item){
result.push(item);
}
});
}else if(options.type=='pair'){
temps = reverseId(id,data['sex']);
temps.forEach(function(r_id){
let pairs = getPairsById(id,r_id);
result = result.concat(pairs);
});
}else{
temps.forEach(function(id){
if (options.type === 'chain') {
return temps.map(id => getChainById(id, sex)).filter(item => item);
} else if (options.type === 'pair') {
const reversedTemps = reverseId(id, data['sex']);
return reversedTemps.flatMap(rId => getPairsById(id, rId));
} else {
return temps.flatMap(id => {
let items = getItemsById(id);
if(!items.length){
items = getItemsById(sex+','+id);
if (!items.length) {
items = getItemsById(sex + ',' + id);
}
result = result.concat(items);
return items;
});
}
});
});
});
});
// console.log('[result]',result);
return [...new Set(result)];
};
@ -86,4 +73,4 @@ relationship.dataCount = Object.keys(modeData).length;
// 设置语言模式
relationship.setMode = setModeData;
export default relationship;
export default relationship;