updated 将方法进行模块化管理

This commit is contained in:
PASSER-BY 2022-11-27 00:10:12 +08:00
parent adcbd8530b
commit 7a0911d27d
18 changed files with 370 additions and 341 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,6 @@
// 分支关系链
/*
* 分支关系链 - 旁支亲戚的分支关系链
*/
export default {
// 其他旁系
'{G2}':['祖父'],

View File

@ -1,4 +1,6 @@
// 主要关系链
/*
* 主要关系链
*/
export default {
'':['自己','我','俺','吾','本人','在下'],
// 主线

View File

@ -1,4 +1,6 @@
// 并称关系链
/*
* 并称关系链 - 某个称呼同时包含多层关系链
*/
export default {
'[f,f|f,m|m,f],[f,m],f':['老太奶爷','祖太奶爷'],
'[f,f|f,m|m,f],[f,m],m':['老太奶奶','祖太奶奶'],

View File

@ -1,4 +1,6 @@
// 关系合称
/*
* 关系合称 - 两个人之间的关系合称
*/
export default {
'f#s':['父子'],
'm#s':['母子'],

View File

@ -1,4 +1,6 @@
// 分支前缀
/*
* 分支前缀 - 旁支亲戚的分支节点
*/
export default {
'{G2C}':{
'[f|m],[f|m],[f|m],[f,xs|m,xb|m,xs],[s|d],[s|d]':['重表'], // 曾祖辈的表兄弟姐妹的子女

209
src/module/id.js Normal file
View File

@ -0,0 +1,209 @@
/*
* 标识符 - 唯一性关系链关系链转换成中文表述
*/
import _pair from './data/pair';
import {number2zh} from './unit';
import {selector2id} from './selector';
import {modeData as _data} from './mode';
// 逆转ID
export function reverseId(id,sex){
var hash = {
f:['d','s'],
m:['d','s'],
h:['w',''],
w:['','h'],
s:['m','f'],
d:['m','f'],
lb:['os','ob'],
ob:['ls','lb'],
xb:['xs','xb'],
ls:['os','ob'],
os:['ls','lb'],
xs:['xs','xb']
};
var age = '';
if(id.match(/&o$/)){
age = '&l';
}else if(id.match(/&l$/)){
age = '&o';
}
if(id){
id = id.replace(/&[ol\d+]/g,'');
//性别判断
if(sex<0){
if(id.match(/^w/)){
sex = 1;
}else if(id.match(/^h/)){
sex = 0;
}
}
var result = [];
var doing = function(sex){
var sid = (','+sex+','+id).replace(/,[fhs]|,[olx]b/g,',1').replace(/,[mwd]|,[olx]s/g,',0');
sid = sid.substring(0,sid.length-2);
var id_arr = id.split(',').reverse();
var sid_arr = sid.split(',').reverse();
var arr = id_arr.map((id,i)=>hash[id][sid_arr[i]]);
var r_id = arr.join(',');
var gen = getGenById(r_id);
return r_id +(gen?'':age);
};
if(sex<0){
result.push(doing(1));
result.push(doing(0));
}else{
result.push(doing(sex));
}
return result;
}
return [''];
};
// 通过ID获取世代数
export function getGenById(id){
var gMap = {'f':1,'m':1,'s':-1,'d':-1};
var arr = id.split(',');
var gen = 0;
arr.forEach(function(sub){
var s = sub.replace(/&[ol\d]+/,'');
gen += gMap[s]||0;
});
return gen;
};
// 通过ID获取关系称呼
export function getItemsById(id){
var items = [];
var getData = function(key){
var res = [];
if(_data[key]){
res.push(_data[key][0]);
}else{
for(var i in _data){
if(i.replace(/&[ol]/g,'')==key){
res.push(_data[i][0]);
}else{
while (key.match(/[ol](b|s)/)){
key = key.replace(/[ol](b|s)/,'x$1');
if(key==i){
res.push(_data[i][0]);
break;
}
}
}
}
}
return res;
};
// 对排序进行处理
if(id.match(/&([\d]+)(,[hw])?$/)){
var num = id.match(/&([\d]+)(,[hw])?$/)[1];
var zh = number2zh(num);
id = id.replace(/&\d+/g,'');
if(_data[id]){
var item = '';
var gen = getGenById(id);
if(gen<3&&!id.match(/[hw],/)){
_data[id].forEach(function(name){
if(!item&&name.includes('几')){
item = name.replace('几',zh);
}
});
if(!item){
item = _data[id][0].match(/^[大小]/)?_data[id][0].replace(/^[大小]/,zh):zh+_data[id][0];
}
}else{
item = _data[id][0]
}
items.push(item);
}
}else{
id = id.replace(/&\d+/g,'');
}
// 直接匹配称呼
if(!items.length){
items = getData(id);
}
// 忽略年龄条件查找
if(!items.length){
id = id.replace(/&[ol]/g,'');
items = getData(id);
}
// 忽略年龄条件查找
if(!items.length){
id = id.replace(/[ol](b|s)/g,'x$1');
items = getData(id);
}
// 缩小访问查找
if(!items.length){
var l = id.replace(/x/g,'l');
var o = id.replace(/x/g,'o');
items = items.concat(getData(o),getData(l));
}
return items;
};
// 通过ID获取关系链
export function getChainById(id,sex){
var arr = id.split(',');
var item = arr.map(function(sign){
var key = sign.replace(/&[ol\d]+/,'');
var data = Object.assign({},_data,{
'xb':['兄弟'],
'xs':['姐妹']
});
return data[key][0];
}).join('的');
if(sex&&sex>-1&&_data[sex+','+id]){
if(sex==0){
item = '(女性)'+item;
}else if(sex==1){
item = '(男性)'+item;
}
}
return item
};
// 通过ID获取关系合称
export function getPairsById(id1,id2){
var result = [];
var result_x = [];
var result_r = [];
id1 = id1.replace(/&\d+/,'');
id2 = id2.replace(/&\d+/,'');
var id1_x = id1.replace(/([ol])([bs])/,'x$2');
var id2_x = id2.replace(/([ol])([bs])/,'x$2');
var id1_r = id1.replace(/&[ol]/,'');
var id2_r = id2.replace(/&[ol]/,'');
for(var key in _pair){
var selectors = key.split('#');
if(selectors.length>1){
var list1 = selector2id(selectors[0]);
var list2 = selector2id(selectors[1]);
var list1_r = list1.map(function(selector){
return selector.replace(/&[ol\d]+/,'').replace(/([ol])([bs])/,'x$2');
});
var list2_r = list2.map(function(selector){
return 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]);
}
if(list1_r.includes(id1_x)&&list2_r.includes(id2_x)||list1_r.includes(id2_x)&&list2_r.includes(id1_x)){
result_x.push(_pair[key][0]);
}
if(list1_r.includes(id1_r)&&list2_r.includes(id2_r)||list1_r.includes(id2_r)&&list2_r.includes(id1_r)){
result_r.push(_pair[key][0]);
}
}
}
if(!result.length){
result = result_x;
}
if(!result.length){
result = result_r;
}
return result;
};

View File

@ -1,12 +1,14 @@
// 完整关系链数据 - 合并各类关系链数据
/*
* 完整关系链数据 - 合并各类关系链数据
*/
import _prefix from './data/prefix';
import _branch from './data/branch';
import _main from './data/main';
import _multipie from './data/multiple';
import {
selectorFormat
} from './method';
expandSelector
} from './selector';
var _map = Object.assign({},_multipie);
@ -15,7 +17,7 @@ var prefixMap = {};
for(var key in _prefix){
prefixMap[key] = {};
for(var selector in _prefix[key]){
selectorFormat(selector).forEach(function(s){
expandSelector(selector).forEach(function(s){
prefixMap[key][s] = _prefix[key][selector];
});
}

26
src/module/mode.js Normal file
View File

@ -0,0 +1,26 @@
/*
* 模式数据
*/
import _map from './map';
var _cache = {}; // 模式缓存
var _data = Object.assign({},_map); // 最终数据
// 设置模式数据
export function setModeData(sign,data){
_cache[sign] = Object.assign(_cache[sign]||{},data);
};
// 获取模式数据
export function getModeData(sign){
_data = Object.assign({},_map);
if(sign&&_cache[sign]){
for(var key in _cache[sign]){
_data[key] = [].concat(_cache[sign][key],_map[key]||[]);
}
}
return _data;
};
// 获取数据
export {_data as modeData};

14
src/module/options.js Normal file
View File

@ -0,0 +1,14 @@
/*
* 通过表达式获取配置
*/
import _expression from './rule/expression';
export function getOptions(text){
for(var item of _expression){
var match = text.match(item['exp']);
if(match){
return item['opt'](match);
}
}
return {};
};

View File

@ -1,4 +1,6 @@
// 自然语言表达 - 将语句表达转换成参数调用
/*
* 自然语言表达 - 语言表达转换成参数调用
*/
export default [
{
exp:/^(\S+?)(应该|得)?(称呼|叫|喊)(\S+?)(什么|啥)?$/,

View File

@ -1,5 +1,6 @@
// 关系链缩写规则 - 将关系链转换成最短关系链
/*
* 关系链缩写规则 - 关系链缩减成最简表达
*
* 关系数据语法说明
* 关系符 f:; m:; h:; w:; s:; d:; xb:兄弟; ob:; lb:; xs:姐妹; os:; ls:
* 修饰符 1:男性; 0:女性; &o:年长; &l:年幼; &\d+:排序 #:隔断; [a|b]:并列

View File

@ -1,4 +1,6 @@
// 词义扩展 - 对称呼词义进行扩展
/*
* 词义扩展 - 对称呼词义进行扩展
*/
export default [
{
exp:/^从表/,

View File

@ -1,4 +1,6 @@
// 同义词替换 - 对称呼中的近义词进行替换
/*
* 同义词替换 - 对称呼中的近义词进行替换
*/
export default {
'晜':'兄',
'哥':'兄',

View File

@ -1,54 +1,13 @@
// 通用方法
/*
* 选择器 - 非唯一性关系链中文表述转换为关系链
*/
import _filter from './rule/filter';
import _expression from './rule/expression';
import _replace from './rule/replace';
import _similar from './rule/similar';
import _map from './map';
import _pair from './data/pair';
var _mode = {}; // 模式数据
var _data = Object.assign({},_map); // 最终数据
// 中文数字转阿拉伯数字
var zh2number = function(text){
var num = 0;
var map = {'大':1,'小':99};
var textAttr = ['','一','二','三','四','五','六','七','八','九','十'];
if(map[text]){
num = map[text];
}else{
var [unit,dec=0] = text.replace(/^十/,'一十').split('十').map(word=> textAttr.indexOf(word)).reverse();
num = dec*10+unit;
}
return num;
};
// 阿拉伯数字转中文数字
var number2zh = function(num){
var text = '';
var map = {1:'大',99:'小'};
var textAttr = ['','一','二','三','四','五','六','七','八','九','十'];
if(map[num]){
text = map[num];
}else{
var dec = ~~(num/10);
var unit = num%10;
text = (dec?(textAttr[dec]+'十').replace('一十','十'):'')+textAttr[unit];
}
return text;
};
// 获得代数
var getGen = function(id){
var gMap = {'f':1,'m':1,'s':-1,'d':-1};
var arr = id.split(',');
var gen = 0;
arr.forEach(function(sub){
var s = sub.replace(/&[ol\d]+/,'');
gen += gMap[s]||0;
});
return gen;
};
import {zh2number} from './unit';
import {reverseId,getGenById} from './id';
import {modeData as _data} from './mode';
// 获得最简
var getOptimal = function(options){
@ -62,7 +21,7 @@ var getOptimal = function(options){
sex = from_chain[i].match(/^([fhs1](&[ol\d]+)?|[olx]b)(&[ol\d]+)?/)?1:0;
continue;
}else{
if(getGen(from_chain[i])==getGen(to_chain[i])&&from_chain[i].match(/^[xol][bs]|^[sd]/)){
if(getGenById(from_chain[i])==getGenById(to_chain[i])&&from_chain[i].match(/^[xol][bs]|^[sd]/)){
var from_match = from_chain[i].match(/&([ol\d]+)/);
var to_match = to_chain[i].match(/&([ol\d]+)/);
if(!from_match){
@ -111,8 +70,8 @@ var getOptimal = function(options){
};
};
// 数组去重
export function unique(arr){
// 去重
var unique = function(arr){
var sameList = arr.filter(item=>item==item.replace(/[ol](?=s|b)/,'x').replace(/&[ol]/,''));
return arr.filter(item=>{
var temp = item.replace(/[ol](?=s|b)/,'x').replace(/&[ol]/,'');
@ -290,8 +249,8 @@ export function mergeSelector(param){
return result;
};
// 选择器扩展
export function selectorFormat(selector){
// 扩展选择器
export function expandSelector(selector){
var result = [];
var hash = {};
var getSelector = function(selector){
@ -336,226 +295,14 @@ export function selector2id(selector,sex){
}else if(sex==0&&selector.match(/^,[w1]/)){
return [];
}
// console.log('[selector]',selector);
if(!selector.match(/^,/)){
selector = ','+selector;
}
if(sex>-1&&!selector.includes(',1')&&!selector.includes(',0')){
selector = ','+sex+selector;
}
if(selector.match(/,[mwd0](&[ol\d]+)?,w|,[hfs1](&[ol\d]+)?,h/)){ //同志关系去除
return [];
}
var result = selectorFormat(selector).map(function(selector){
var result = expandSelector(selector).map(function(selector){
return selector.replace(/,[01]/,'').substr(1); //去前面逗号和性别信息
});
return unique(result);
};
// 逆转ID
export function reverseId(id,sex){
var hash = {
f:['d','s'],
m:['d','s'],
h:['w',''],
w:['','h'],
s:['m','f'],
d:['m','f'],
lb:['os','ob'],
ob:['ls','lb'],
xb:['xs','xb'],
ls:['os','ob'],
os:['ls','lb'],
xs:['xs','xb']
};
var age = '';
if(id.match(/&o$/)){
age = '&l';
}else if(id.match(/&l$/)){
age = '&o';
}
if(id){
id = id.replace(/&[ol\d+]/g,'');
//性别判断
if(sex<0){
if(id.match(/^w/)){
sex = 1;
}else if(id.match(/^h/)){
sex = 0;
}
}
var result = [];
var doing = function(sex){
var sid = (','+sex+','+id).replace(/,[fhs]|,[olx]b/g,',1').replace(/,[mwd]|,[olx]s/g,',0');
sid = sid.substring(0,sid.length-2);
var id_arr = id.split(',').reverse();
var sid_arr = sid.split(',').reverse();
var arr = id_arr.map((id,i)=>hash[id][sid_arr[i]]);
var r_id = arr.join(',');
var gen = getGen(r_id);
return r_id +(gen?'':age);
};
if(sex<0){
result.push(doing(1));
result.push(doing(0));
}else{
result.push(doing(sex));
}
return result;
}
return [''];
};
// 通过ID获取关系称呼
export function getItemsById(id){
var items = [];
var getData = function(key){
var res = [];
if(_data[key]){
res.push(_data[key][0]);
}else{
for(var i in _data){
if(i.replace(/&[ol]/g,'')==key){
res.push(_data[i][0]);
}else{
while (key.match(/[ol](b|s)/)){
key = key.replace(/[ol](b|s)/,'x$1');
if(key==i){
res.push(_data[i][0]);
break;
}
}
}
}
}
return res;
};
// 对排序进行处理
if(id.match(/&([\d]+)(,[hw])?$/)){
var num = id.match(/&([\d]+)(,[hw])?$/)[1];
var zh = number2zh(num);
id = id.replace(/&\d+/g,'');
if(_data[id]){
var item = '';
var gen = getGen(id);
if(gen<3&&!id.match(/[hw],/)){
_data[id].forEach(function(name){
if(!item&&name.includes('几')){
item = name.replace('几',zh);
}
});
if(!item){
item = _data[id][0].match(/^[大小]/)?_data[id][0].replace(/^[大小]/,zh):zh+_data[id][0];
}
}else{
item = _data[id][0]
}
items.push(item);
}
}else{
id = id.replace(/&\d+/g,'');
}
// 直接匹配称呼
if(!items.length){
items = getData(id);
}
// 忽略年龄条件查找
if(!items.length){
id = id.replace(/&[ol]/g,'');
items = getData(id);
}
// 忽略年龄条件查找
if(!items.length){
id = id.replace(/[ol](b|s)/g,'x$1');
items = getData(id);
}
// 缩小访问查找
if(!items.length){
var l = id.replace(/x/g,'l');
var o = id.replace(/x/g,'o');
items = items.concat(getData(o),getData(l));
}
return items;
};
// 通过ID获取关系链
export function getChainById(id){
var arr = id.split(',');
return arr.map(function(sign){
var key = sign.replace(/&[ol\d]+/,'');
var data = Object.assign({},_data,{
'xb':['兄弟'],
'xs':['姐妹']
});
return data[key][0];
}).join('的');
};
// 通过ID获取关系合称
export function getPairsByIds(id1,id2){
var result = [];
var result_x = [];
var result_r = [];
id1 = id1.replace(/&\d+/,'');
id2 = id2.replace(/&\d+/,'');
var id1_x = id1.replace(/([ol])([bs])/,'x$2');
var id2_x = id2.replace(/([ol])([bs])/,'x$2');
var id1_r = id1.replace(/&[ol]/,'');
var id2_r = id2.replace(/&[ol]/,'');
for(var key in _pair){
var selectors = key.split('#');
if(selectors.length>1){
var list1 = selector2id(selectors[0]);
var list2 = selector2id(selectors[1]);
var list1_r = list1.map(function(selector){
return selector.replace(/&[ol\d]+/,'').replace(/([ol])([bs])/,'x$2');
});
var list2_r = list2.map(function(selector){
return 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]);
}
if(list1_r.includes(id1_x)&&list2_r.includes(id2_x)||list1_r.includes(id2_x)&&list2_r.includes(id1_x)){
result_x.push(_pair[key][0]);
}
if(list1_r.includes(id1_r)&&list2_r.includes(id2_r)||list1_r.includes(id2_r)&&list2_r.includes(id1_r)){
result_r.push(_pair[key][0]);
}
}
}
if(!result.length){
result = result_x;
}
if(!result.length){
result = result_r;
}
return result;
};
// 设置模式数据
export function setMode(sign,data){
_mode[sign] = Object.assign(_mode[sign]||{},data);
};
// 获取模式数据
export function getDataByMode(sign){
_data = Object.assign({},_map);
if(sign&&_mode[sign]){
for(var key in _mode[sign]){
_data[key] = [].concat(_mode[sign][key],_map[key]||[]);
}
}
return _data;
};
// 获取配置
export function getOptions(text){
for(var item of _expression){
var match = text.match(item['exp']);
if(match){
return item['opt'](match);
}
}
return {};
};

32
src/module/unit.js Normal file
View File

@ -0,0 +1,32 @@
/*
* 数值转换
*/
// 中文数字转阿拉伯数字
export function zh2number(text){
var num = 0;
var map = {'大':1,'小':99};
var textAttr = ['','一','二','三','四','五','六','七','八','九','十'];
if(map[text]){
num = map[text];
}else{
var [unit,dec=0] = text.replace(/^十/,'一十').split('十').map(word=> textAttr.indexOf(word)).reverse();
num = dec*10+unit;
}
return num;
};
// 阿拉伯数字转中文数字
export function number2zh(num){
var text = '';
var map = {1:'大',99:'小'};
var textAttr = ['','一','二','三','四','五','六','七','八','九','十'];
if(map[num]){
text = map[num];
}else{
var dec = ~~(num/10);
var unit = num%10;
text = (dec?(textAttr[dec]+'十').replace('一十','十'):'')+textAttr[unit];
}
return text;
};

View File

@ -1,17 +1,7 @@
import {
unique,
getOptions,
getSelectors,
mergeSelector,
selector2id,
reverseId,
getItemsById,
getChainById,
getPairsByIds,
setMode,
getDataByMode
} from './module/method';
var _data = getDataByMode(); // 最终数据
import {getOptions} from './module/options';
import {getSelectors,mergeSelector,selector2id} from './module/selector';
import {reverseId,getItemsById,getChainById,getPairsById} from './module/id';
import {setModeData,getModeData,modeData as _data} from './module/mode';
// 对外方法
var relationship = function (parameter){
@ -27,7 +17,7 @@ var relationship = function (parameter){
mode:'default', // 模式选择使用setMode方法定制不同地区模式在此选择自定义模式
optimal:false // 最短关系:计算两者之间的最短关系
},parameter);
_data = getDataByMode(options.mode);
_data = getModeData(options.mode);
var from_selectors = getSelectors(options.text);
var to_selectors = getSelectors(options.target);
if(!to_selectors.length){
@ -44,61 +34,53 @@ var relationship = function (parameter){
optimal:options.optimal
}).forEach(function(data){
// console.log('[data]',from_selector,to_selector,data);
var ids = data?selector2id(data['selector'],data['sex']):null;
var ids = data?selector2id(data['selector'],data['sex']):[];
// console.log('[ids]',data['selector'],data['sex'],ids);
if(ids){
ids.forEach(function(id){
var temps = [id];
var sex = data['sex'];
if(options.reverse){
temps = reverseId(id,sex);
if(id.match(/([fhs1](&[ol\d]+)?|[olx]b)$/)){
sex = 1;
}else{
sex = 0;
}
}
if(options.type=='chain'){
temps.forEach(function(id){
var item = getChainById(id);
if(data['sex']>-1&&_data[data['sex']+','+id]){
if(data['sex']==0){
item = '(女性)'+item;
}else if(data['sex']==1){
item = '(男性)'+item;
}
}
if(item){
result.push(item);
}
});
}else if(options.type=='pair'){
temps = reverseId(id,data['sex']);
temps.forEach(function(r_id){
var pairs = getPairsByIds(id,r_id);
result = result.concat(pairs);
});
ids.forEach(function(id){
var temps = [id];
var sex = data['sex'];
if(options.reverse){
temps = reverseId(id,sex);
if(id.match(/([fhs1](&[ol\d]+)?|[olx]b)$/)){
sex = 1;
}else{
temps.forEach(function(id){
var items = getItemsById(id);
if(!items.length){
items = getItemsById(sex+','+id);
}
result = result.concat(items);
});
sex = 0;
}
});
}
}
if(options.type=='chain'){
temps.forEach(function(id){
var 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){
var pairs = getPairsById(id,r_id);
result = result.concat(pairs);
});
}else{
temps.forEach(function(id){
var items = getItemsById(id);
if(!items.length){
items = getItemsById(sex+','+id);
}
result = result.concat(items);
});
}
});
});
});
});
return unique(result);
return [...new Set(result)];
};
// 获取数据表
relationship.data = _data;
// 获取数据量
relationship.dataCount = Object.keys(_data).length;
// 设置语言模式
relationship.setMode = setMode;
relationship.setMode = setModeData;
export default relationship;