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

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;