updated 重写底层逻辑,支持排序参与计算

This commit is contained in:
PASSER-BY 2022-09-03 01:48:27 +08:00
parent 73dc03cec6
commit 2f118960df
9 changed files with 413 additions and 254 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,7 +1,6 @@
{
"name": "relationship.js",
"officialName": "relationship",
"version": "1.1.0",
"version": "1.2.0",
"summary": "relationship.js is a javascript library for chinese family relationship. 中国家庭亲戚称谓计算器,家庭关系、亲戚关系算法。",
"description": "Chinese kinship library",
"author": "HaoLe Zheng",

View File

@ -1,7 +1,7 @@
/*
* 关系数据语法说明
* 关系符 f:; m:; h:; w:; s:; d:; xb:兄弟; ob:; lb:; xs:姐妹; os:; ls:
* 修饰符 1:男性; 0:女性; &o:年长; &l:年幼; #:隔断; [a|b]:并列
* 修饰符 1:男性; 0:女性; &o:年长; &l:年幼; &\d+:排序 #:隔断; [a|b]:并列
*/
// 关系链缩写规则
export default [
@ -15,49 +15,45 @@ export default [
str:'$1$2'
},
{//有大有小,增加不确定性
exp:/^(.+)?,o([sb])([^#]+)&l/g,
str:'$1,x$2$3'
exp:/^(.+)?,o([sb](&\d+)?)([^#]+)&l/g,
str:'$1,x$2$4'
},
{//有大有小,增加不确定性
exp:/^(.+)?,l([sb])([^#]+)&o/g,
str:'$1,x$2$3'
},
{//隔代跨越,增加不确定性
exp:/(,[ds],(.+),[ds])&[ol]/g,
str:'$1'
exp:/^(.+)?,l([sb](&\d+)?)([^#]+)&o/g,
str:'$1,x$2$4'
},
/* 兄弟姐妹 */
{//哥哥姐姐的哥哥姐姐还是自己的哥哥姐姐(年龄判断)
exp:/(,o[sb])+(,o[sb])/,
str:'$2'
exp:/(,o[sb](&\d+)?)+(,o[sb])(&\d+)?/,
str:'$3$4'
},
{//弟弟妹妹的弟弟妹妹还是自己的弟弟妹妹(年龄判断)
exp:/(,l[sb])+(,l[sb])/,
str:'$2'
exp:/(,l[sb](&\d+)?)+(,l[sb])(&\d+)?/,
str:'$3$4'
},
{//如果自己是男性,兄弟姐妹的兄弟就是自己的兄弟或自己
exp:/^(.*)(,[fh1])(,[olx][sb])+,[olx]b(.*)$/,
str:'$1$2,xb$4#$1$2$4'
exp:/^(.*,[fh1])(,[olx][sb](&\d+)?)+,[olx]b(.*)$/,
str:'$1,xb$4#$1$4'
},
{//如果自己是女性,兄弟姐妹的姐妹就是自己的姐妹或自己
exp:/^(.*)(,[mw0])(,[olx][sb])+,[olx]s(.*)$/,
str:'$1$2,xs$4#$1$2$4'
exp:/^(.*,[mw0])(,[olx][sb](&\d+)?)+,[olx]s(.*)$/,
str:'$1,xs$4#$1$4'
},
{//如果自己是男性,兄弟姐妹的姐妹就是自己的姐妹
exp:/(,[fh1])(,[olx][sb])+,[olx]s/g,
exp:/(,[fh1])(,[olx][sb](&\d+)?)+,[olx]s/g,
str:'$1,xs'
},
{//如果自己是女性,兄弟姐妹的兄弟就是自己的兄弟
exp:/(,[mw0])(,[olx][sb])+,[olx]b/g,
exp:/(,[mw0])(,[olx][sb](&\d+)?)+,[olx]b/g,
str:'$1,xb'
},
{//不知道性别,兄弟姐妹的兄弟是兄弟或自己
exp:/^,[olx][sb],[olx]b(.+)?$/,
str:',xb$1#$1'
exp:/^,[olx][sb](&\d+)?,[olx]b(.+)?$/,
str:',xb$2#$2'
},
{//不知道性别,兄弟姐妹的姐妹是姐妹或自己
exp:/^,[olx][sb],[olx]s(.+)?$/,
str:',xs$1#$1'
exp:/^,[olx][sb](&\d+)?,[olx]s(.+)?$/,
str:',xs$2#$2'
},
{//将复合称谓拆分
exp:/^,x([sb])$/,
@ -73,32 +69,40 @@ export default [
str:'m'
},
{//兄弟的父母就是自己的父母
exp:/,[xol][sb](,[mf])/g,
str:'$1'
exp:/,[xol][sb](&\d+)?(,[mf])/g,
str:'$2'
},
/* 父母的子女 */
{//父母的女儿排序判断姐妹的排序
exp:/,[mf],d(&\d+)/,
str:',xs$1'
},
{//父母的女儿年龄判断是姐姐还是妹妹
exp:/,[mf],d&([ol])/,
str:',$1s'
},
{//父母的儿子排序判断兄弟的排序
exp:/,[mf],s(&\d+)/,
str:',xb$1'
},
{//父母的儿子年龄判断是哥哥还是弟弟
exp:/,[mf],s&([ol])/,
str:',$1b'
},
{//如果自己是男性,父母的儿子是兄弟或者自己
exp:/^(.*)(,[fh1]|[xol]b),[mf],s(.*)$/,
str:'$1$2,xb$3#$1$2$3'
exp:/^(.*,[fh1]|[xol]b(&\d+)?),[mf],s(.*)$/,
str:'$1,xb$3#$1$3'
},
{//如果自己是女性,父母的女儿是姐妹或者自己
exp:/^(.*)(,[mw0]|[xol]s),[mf],d(.*)$/,
str:'$1$2,xs$3#$1$2$3'
exp:/^(.*,[mw0]|[xol]s(&\d+)?),[mf],d(.*)$/,
str:'$1,xs$3#$1$3'
},
{//如果自己是女性,父母的儿子是自己的兄弟
exp:/(,[mw0]|[xol]s),[mf],s/,
exp:/(,[mw0]|[xol]s(&\d+)?),[mf],s/,
str:'$1,xb'
},
{//如果自己是男性,父母的女儿是自己的姐妹
exp:/(,[fh1]|[xol]b),[mf],d/,
exp:/(,[fh1]|[xol]b(&\d+)?),[mf],d/,
str:'$1,xs'
},
{//父母的儿子是兄弟或自己
@ -110,7 +114,15 @@ export default [
str:',xs$1#,0$1'
},
/* 孩子 */
{//孩子的姐妹是自己的女儿(年龄判断)
{//孩子的兄弟是自己的儿子(排序判断)
exp:/,[ds](&[ol\d]+)?,[olx]b(&\d+)/g,
str:',s$2'
},
{//孩子的姐妹是自己的女儿(排序判断)
exp:/,[ds](&[ol\d]+)?,[olx]s(&\d+)/g,
str:',d$2'
},
{//孩子的兄弟是自己的儿子(年龄判断)
exp:/,[ds]&o,ob/g,
str:',s&o'
},
@ -122,33 +134,33 @@ export default [
exp:/,[ds]&l,lb/g,
str:',s&l'
},
{//孩子的兄弟是自己的儿子(年龄判断)
{//孩子的姐妹是自己的女儿(年龄判断)
exp:/,[ds]&l,ls/g,
str:',d&l'
},
{//孩子的姐妹是自己的女儿
exp:/,[ds](&[ol])?,[olx]s/g,
str:',d'
exp:/,[ds](&[ol\d]+)?,[olx]s(&\d+)?/g,
str:',d$2'
},
{//孩子的兄弟是自己的儿子
exp:/,[ds](&[ol])?,[olx]b/g,
str:',s'
exp:/,[ds](&[ol\d]+)?,[olx]b(&\d+)?/g,
str:',s$2'
},
/* 夫妻 */
{//自己是女性,女儿或儿子的妈妈是自己
exp:/(,[mwd0](&[ol])?|[olx]s),[ds](&[ol])?,m/g,
exp:/(,[mwd0]|,[olx]s)(&[ol\d]+)?,[ds](&[ol\d]+)?,m/g,
str:'$1'
},
{//自己是女性,女儿或儿子的爸爸是自己的丈夫
exp:/(,[mwd0](&[ol])?|[olx]s),[ds](&[ol])?,f/g,
exp:/(,[mwd0]|,[olx]s)(&[ol\d]+)?,[ds](&[ol\d]+)?,f/g,
str:'$1,h'
},
{//自己是男性,女儿或儿子的爸爸是自己
exp:/(,[fhs1](&[ol])?|[olx]b),[ds](&[ol])?,f/g,
exp:/(,[fhs1]|,[olx]b)(&[ol\d]+)?,[ds](&[ol\d]+)?,f/g,
str:'$1'
},
{//自己是男性,女儿或儿子的妈妈是自己的妻子
exp:/(,[fhs1](&[ol])?|[olx]b),[ds](&[ol])?,m/g,
exp:/(,[fhs1]|,[olx]b)(&[ol\d]+)?,[ds](&[ol\d]+)?,m/g,
str:'$1,w'
},
{//不知道性别,子女的妈妈是妻子或自己

View File

@ -206,8 +206,8 @@ export default {
'f,f,ob,w':['伯婆','姆婆','大奶奶'],
'f,f,lb':['叔公','叔祖','叔翁','小爷爷','晚公','幺爷','细嗲'],
'f,f,lb,w':['叔婆','婶婆','晚婆','幺奶','小奶奶'],
'f,f,xb':['祖父','从祖父','几爷爷','几大爷','几嗲','几爷','几公'],
'f,f,xb,w':['祖母','从祖母','几奶奶','几大娘','几奶','几婆'],
'f,f,xb':['伯叔祖父','从祖父','几爷爷','几大爷','几嗲','几爷','几公'],
'f,f,xb,w':['伯叔祖母','从祖母','几奶奶','几大娘','几奶','几婆'],
'f,f,xs':['姑奶奶','祖姑','恩婆'],
'f,f,xs,h':['姑爷爷','姑公公','恩爹','祖姑丈','姑丈公','丈公'],
'f,m,xb':['舅爷爷','舅祖','舅爹','太舅父'],
@ -228,12 +228,12 @@ export default {
'm,m,xs,h':['姨外公','姨公','外姨丈公','外丈公'],
// 父系
'f':['爸爸','父亲','老父亲','老爸','阿爸','阿父','阿爹','老窦','爹地','依爹','老爹','老汉','老爷子','老子','牙老子','爸','父','爹','老汉儿','牙老倌','爸比','爹爹','爹啲','一世祖'],
'f,ob':['伯父','伯伯','伯爸','伯爷','依伯','世父','大爷','大爸','大爸爸','大爹','伯儿','大伯','大大','阿伯','伯'],
'f,ob':['伯父','伯伯','伯爸','伯爷','依伯','世父','大爷','大爸','大爸爸','大爹','伯儿','大伯','大大','阿伯','几伯','伯'],
'f,ob,w':['伯母','伯妈','伯娘','依姆','世母','大娘','大妈','大妈妈','大嬷','伯妇','大嬷','大姆妈','伯姐','姆'],
'f,lb':['叔叔','叔父','叔爸','叔爹','阿叔','叔儿','仲父','季父','叔仔','依叔','小叔','小爹','小爸','尕爸','幺爸','幺爹','幺叔','细叔','满叔','晚叔','叔'],
'f,lb,w':['婶婶','婶母','婶妈','婶娘','阿婶','婶儿','仲母','季母','叔妇','依婶','小婶','小娘','小妈','尕婶','幺妈','幺娘','幺婶','细婶','满婶','晚婆','婶','婶子','家婶','叔母','叔妈','叔娘','婶爹'],
'f,[ob|lb]':['伯叔父','叔伯','几爸爸','几爸','几爹'],
'f,[ob|lb],w':['伯叔母','几妈妈','几妈','几娘'],
'f,lb':['叔叔','叔父','叔爸','叔爹','阿叔','叔儿','仲父','季父','叔仔','依叔','小叔','小爹','小爸','尕爸','幺爸','幺爹','幺叔','细叔','满叔','晚叔','几叔','叔'],
'f,lb,w':['婶婶','婶母','婶妈','婶娘','阿婶','婶儿','仲母','季母','叔妇','依婶','小婶','小娘','小妈','尕婶','幺妈','幺娘','幺婶','细婶','满婶','晚婆','几婶','婶','婶子','家婶','叔母','叔妈','叔娘','婶爹'],
'f,xb':['伯叔父','叔伯','几爸爸','几爸','几爹'],
'f,xb,w':['伯叔母','几妈妈','几妈','几娘'],
'f,xb,s&o':['堂哥','堂阿哥','堂房哥哥','堂房阿哥','叔伯哥哥','叔伯阿哥','堂老兄'],
'f,xb,s&o,w':['堂嫂','堂兄嫂'],
'f,xb,s&l':['堂弟','堂阿弟','堂房弟弟','堂房阿弟','叔伯弟弟','叔伯老弟','堂老弟'],
@ -257,16 +257,14 @@ export default {
'f,os,h':['大姑丈','大姑父','大姑爸','恩伯'],
'f,ls':['小姑','小姑妈','姑姐','姑妹','姑仔','尕娘','幺姑','幺姑姐','老姑','细姑','满姑'],
'f,ls,h':['小姑丈','小姑父','小姑爹','恩叔'],
'f,xs':['姑妈','姑母','姑姑','恩妈','嬢嬢','娘娘','姑','阿姑'],
'f,xs':['姑妈','姑母','姑姑','恩妈','嬢嬢','娘娘','几姑','姑','阿姑'],
'f,xs,h':['姑丈','姑父','姑爸','恩爸','姑爹','姑夫','姑婿','亘'],
'f,f,[ob|lb]':['伯叔祖父'],
'f,f,[ob|lb],w':['伯叔祖母'],
'f,f,xb,s&o':['堂伯'],
'f,f,xb,s&o,w':['堂伯母'],
'f,f,xb,s&l':['堂叔'],
'f,f,xb,s&l,w':['堂婶'],
'f,f,xb,[s&o|s&l]':['堂伯叔父','堂叔伯','从父'],
'f,f,xb,[s&o|s&l],w':['堂伯叔母','从母'],
'f,f,xb,s':['堂伯叔父','堂叔伯','从父'],
'f,f,xb,s,w':['堂伯叔母','从母'],
'f,f,xb,s,s&o':['从堂兄'],
'f,f,xb,s,s&l':['从堂弟'],
'f,f,xb,s,s,s':['从堂侄','三从子'],
@ -275,47 +273,47 @@ export default {
'f,f,xb,s,s,s,s,s,s':['从堂侄玄孙','三玄孙'],
'f,f,xb,d':['堂姑'],
'f,f,xb,d,h':['堂姑丈'],
'f,f,f,[ob|lb]':['伯叔曾祖父'],
'f,f,f,[ob|lb],w':['伯叔曾祖母'],
'f,f,f,xb,[s&o|s&l]':['堂伯叔祖父'],
'f,f,f,xb,[s&o|s&l],w':['堂伯叔祖母'],
'f,f,f,xb':['伯叔曾祖父'],
'f,f,f,xb,w':['伯叔曾祖母'],
'f,f,f,xb,s':['堂伯叔祖父'],
'f,f,f,xb,s,w':['堂伯叔祖母'],
'f,f,f,xb,s,s&o':['从伯父'],
'f,f,f,xb,s,s&o,w':['从伯母'],
'f,f,f,xb,s,s&l':['从叔父'],
'f,f,f,xb,s,s&l,w':['从叔母'],
'f,f,f,xb,s,[s&o|s&l]':['从伯叔父','再从父'],
'f,f,f,xb,s,[s&o|s&l],w':['从伯叔母','再从母'],
'f,f,f,xb,s,s':['从伯叔父','再从父'],
'f,f,f,xb,s,s,w':['从伯叔母','再从母'],
'f,f,f,xb,s,s,s&o':['族兄'],
'f,f,f,xb,s,s,s&l':['族弟'],
'f,f,f,xb,s,s,s,s':['族侄','四从子','族子'],
'f,f,f,xb,s,s,s,s,s':['族侄孙','四从孙','族孙'],
'f,f,f,xb,s,s,s,s,s,s':['族侄曾孙','四曾孙','族曾孙'],
'f,f,f,xb,s,s,s,s,s,s,s':['族侄玄孙','四玄孙','族玄孙'],
'f,f,f,f,[ob|lb]':['伯叔高祖父'],
'f,f,f,f,[ob|lb],w':['伯叔高祖母'],
'f,f,f,f,xb,[s&o|s&l]':['堂伯叔曾祖父'],
'f,f,f,f,xb,[s&o|s&l],w':['堂伯叔曾祖母'],
'f,f,f,f,xb,s,[s&o|s&l]':['从伯叔祖父'],
'f,f,f,f,xb,s,[s&o|s&l],w':['从伯叔祖母'],
'f,f,f,f,xb':['伯叔高祖父'],
'f,f,f,f,xb,w':['伯叔高祖母'],
'f,f,f,f,xb,s':['堂伯叔曾祖父'],
'f,f,f,f,xb,s,w':['堂伯叔曾祖母'],
'f,f,f,f,xb,s,s':['从伯叔祖父'],
'f,f,f,f,xb,s,s,w':['从伯叔祖母'],
'f,f,f,f,xb,s,s,s&o':['族伯父'],
'f,f,f,f,xb,s,s,s&o,w':['族伯母'],
'f,f,f,f,xb,s,s,s&l':['族叔父'],
'f,f,f,f,xb,s,s,s&l,w':['族叔母'],
'f,f,f,f,xb,s,s,[s&o|s&l]':['族伯叔父','三从父','族父'],
'f,f,f,f,xb,s,s,[s&o|s&l],w':['族伯叔母','三从母','族母'],
'f,f,f,f,xb,s,s,s':['族伯叔父','三从父','族父'],
'f,f,f,f,xb,s,s,s,w':['族伯叔母','三从母','族母'],
// 母系
'm':['妈妈','母亲','老母亲','老妈','阿妈','阿母','阿娘','老母','妈咪','依妈','老娘','老乸','老妈子','妈子','娘老子','妈','母','娘','阿毑','姆嬷','姆妈','娘亲'],
'm,ob':['大舅','大舅舅','舅伯','元舅'],
'm,ob,w':['大舅妈','大妗','舅嫲'],
'm,lb':['小舅','小舅舅','舅仔','舅父仔','幺舅','老舅','细舅','满舅','尕阿舅'],
'm,lb,w':['小舅妈','小妗','细妗'],
'm,xb':['舅舅','舅爸','舅父','舅爹','娘舅','母舅','阿舅','妗公','舅'],
'm,xb':['舅舅','舅爸','舅父','舅爹','娘舅','母舅','阿舅','妗公','几舅','舅'],
'm,xb,w':['舅妈','舅母','舅娘','舅妻','舅姆','舅姆妈','舅媳妇','舅妇','舅姥','老妗','妗子','妗妗','妗妈','妗娘','妗母','阿妗','妗门','妗婆仔','妗儿妈','妗'],
'm,os':['大姨','大姨妈'],
'm,os,h':['大姨丈','大姨父','大姨爸','姨伯'],
'm,ls':['小姨','小姨妈','姨仔','幺姨','老姨','满姨','细姨','尕姨娘'],
'm,ls,h':['小姨丈','小姨父','小姨爹','老姨夫','姨叔'],
'm,xs':['姨妈','姨母','姨姨','姨娘','阿姨','姨','从母'],
'm,xs':['姨妈','姨母','姨姨','姨娘','阿姨','几姨','姨','从母'],
'm,xs,h':['姨丈','姨父','姨爸','姨爹','姨夫','姨婿','姨郎','尹'],
'm,f,xb,s':['堂舅'],
'm,f,xb,s,w':['堂舅妈'],
@ -427,7 +425,7 @@ export default {
'w,xs,d,d':['姨甥外孙女','姨外孙女'],
// 兄弟姐妹系
'ob':['哥哥','哥','胞兄','亲哥','老哥','依哥','阿哥','家兄','兄长','大佬','元兄','长兄'],
'ob,w':['嫂子','嫂','嫂嫂','阿嫂','家嫂','兄姊','兄嫂','兄妇','兄妻'],
'ob,w':['大嫂','嫂子','嫂','嫂嫂','阿嫂','家嫂','兄姊','兄嫂','兄妇','兄妻','几嫂'],
'ob,s':['兄子'],
'ob,d':['兄女'],
'lb':['弟弟','弟','胞弟','亲弟','老弟','阿弟','细佬','依弟','小弟','幺弟','细弟','满弟','幼弟'],

View File

@ -6,6 +6,116 @@ import _pair from './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{
if(text.indexOf('十')>-1){
var numAttr = text.split('十');
if(!numAttr[0]){
num = 10;
}else{
num = textAttr.indexOf(numAttr[0])*10;
}
num += textAttr.indexOf(numAttr[1]);
}else{
num += textAttr.indexOf(text)>-1?textAttr.indexOf(text):0;
}
}
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;
if(dec){
if(dec>1){
text = dec<textAttr.length?textAttr[dec]:'';
}
text += '十';
text += unit<textAttr.length?textAttr[unit]:'';
}else{
text += num<textAttr.length?textAttr[num]:'';
}
}
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;
};
// 获得最简
var getOptimal = function(options){
var from = options['from'];
var to = options['to']
var from_chain = options['from'].split(',');
var to_chain = options['to'].split(',');
for(var i=0;i<from_chain.length&&i<to_chain.length;i++){
if(from_chain[i]==to_chain[i]){
from = from_chain.slice(i+1).join(',');
to = to_chain.slice(i+1).join(',');
continue;
}else{
if(getGen(from_chain[i])==getGen(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){
from_match = from_chain[i].match(/([xol])[bs]/);
}
if(!to_match){
to_match = to_chain[i].match(/([xol])[bs]/);
}
var from_attr = from_match?from_match[1]:'';
var to_attr = to_match?to_match[1]:'';
if(!isNaN(from_attr)&&!isNaN(to_attr)){
if(from_attr>to_attr){
from_chain[i] = from_chain[i].replace(/^[xol]b|^s/,'lb').replace(/^[xol]s|^d/,'ls');
from = from_chain.slice(i).join(',');
to = to_chain.slice(i+1).join(',');
}else if(from_attr<to_attr){
from_chain[i] = from_chain[i].replace(/^[xol]b|^s/,'ob').replace(/^[xol]s|^d/,'os');
from = from_chain.slice(i).join(',');
to = to_chain.slice(i+1).join(',');
}
}else if(!isNaN(from_attr)&&to_attr=='o'||from_attr=='l'&&!isNaN(to_attr)){
from_chain[i] = from_chain[i].replace(/^[xol]b|^s/,'lb').replace(/^[xol]s|^d/,'ls');
from = from_chain.slice(i).join(',');
to = to_chain.slice(i+1).join(',');
}else if(!isNaN(from_attr)&&to_attr=='l'||from_attr=='o'&&!isNaN(to_attr)){
from_chain[i] = from_chain[i].replace(/^[xol]b|^s/,'ob').replace(/^[xol]s|^d/,'os');
from = from_chain.slice(i).join(',');
to = to_chain.slice(i+1).join(',');
}
}
break;
}
}
return {
'from':from,
'to':to
};
};
// 数组去重
export function unique(arr){
var sameList = arr.filter(item=>item==item.replace(/[ol](?=s|b)/,'x').replace(/&[ol]/,''));
@ -96,18 +206,26 @@ export function getSelectors(str){
getList(name);
// 通过关键词找关系
keywords.forEach(function(name){
var x_name = name.replace(/^[大|小|老]|^[一|二|三|四|五|六|七|八|九|十]{1,2}/,'几');
var r_name = name.replace(/^[大|小|老]|^[一|二|三|四|五|六|七|八|九|十]{1,2}/,'');
var x_name = name.replace(/^[大|小]|^[一|二|三|四|五|六|七|八|九|十]+/,'几');
var r_name = name.replace(/^[大|小]|^[一|二|三|四|五|六|七|八|九|十]+/,'');
var match = name.match(/^[大|小]|^[一|二|三|四|五|六|七|八|九|十]+/);
for(var i in _data){
var isInclude = false;
if(_data[i].indexOf(name)>-1){
items.push(i);
}
if(name!=x_name&&_data[i].indexOf(x_name)>-1){
x_items.push(i);
}
if(name!=r_name&&_data[i].indexOf(r_name)>-1){
if(!i.match(/^[mf,]+$/)&&!r_name.match(/^[从世]/)){ // 直系祖辈不参与排序
r_items.push(i);
if(match){
if(_data[i].indexOf(x_name)>-1){
var num = zh2number(match[0]);
var r_i = i.replace(/(,[hw])$/,'&'+num+'$1').replace(/(,[^hw]+)$/,'$1&'+num);
x_items.push(r_i);
}
if(_data[i].indexOf(r_name)>-1){
if(!i.match(/^[mf,]+$/)&&!r_name.match(/^[从世]/)){ // 直系祖辈不参与排序
var num = zh2number(match[0]);
var r_i = i.replace(/(,[hw])$/,'&'+num+'$1').replace(/([^hw]+)$/,'$1&'+num);
r_items.push(r_i);
}
}
}
}
@ -139,30 +257,21 @@ export function getSelectors(str){
};
// 合并选择器,查找两个对象之间的关系
export function mergeSelector(options){
var my_sex = options['sex'];
var from = options['from'];
var to = options['to'];
if(from&&to&&options.optimal){
if(from.indexOf(to)==0){
from = from.replace(to,'');
to = '';
}else if(to.indexOf(from)==0){
to = to.replace(from,'');
from = '';
}
}
export function mergeSelector(param){
var from_selector = param['from'];
var to_selector = param['to'];
var my_sex = param['sex'];
if(my_sex<0){
var to_sex = -1;
var from_sex = -1;
if(from.match(/^,[w1]/)){
if(from_selector.match(/^,[w1]/)){
from_sex = 1;
}else if(from.match(/^,[h0]/)){
}else if(from_selector.match(/^,[h0]/)){
from_sex = 0;
}
if(to.match(/^,[w1]/)){
if(to_selector.match(/^,[w1]/)){
to_sex = 1;
}else if(to.match(/^,[h0]/)){
}else if(to_selector.match(/^,[h0]/)){
to_sex = 0;
}
if(from_sex==-1&&to_sex>-1){
@ -172,47 +281,50 @@ export function mergeSelector(options){
}else if(from_sex==to_sex){
my_sex = from_sex;
}else{
return false;
return [];
}
}
var sex = my_sex;
var from_ids = selector2id(from,my_sex);
var to_ids = selector2id(to,my_sex);
var to_rids = [];
var from_ids = selector2id(param['from'],my_sex);
var to_ids = selector2id(param['to'],my_sex);
if(!from_ids.length||!to_ids.length){
return false;
return [];
}
if(to){
var toIsMale = false;
var toIsFemale = false;
to_ids.forEach(function(id){
var selector = ','+id;
if(selector.match(/,([fhs1](&[ol])?|[olx]b)$/)){
toIsMale = true;
var result = [];
from_ids.forEach(function(from){
to_ids.forEach(function(to){
var sex = my_sex;
var selector = ','+to;
if(selector.match(/,([fhs1](&[ol\d]+)?|[olx]b)(&[ol\d]+)?$/)){
sex = 1;
}
if(selector.match(/,([mwd0](&[ol])?|[olx]s)$/)){
toIsFemale = true;
if(selector.match(/,([mwd0](&[ol\d]+)?|[olx]s)(&[ol\d]+)?$/)){
sex = 0;
}
to_rids = to_rids.concat(reverseId(id,my_sex));
if(from&&to){
var isOptimal = param.optimal;
if(from.match(/&\d+/)||to.match(/&\d+/)){
isOptimal = true;
}
if(isOptimal){
var ops = getOptimal({
'from':from,
'to':to
});
from = ops['from'];
to = ops['to'];
}
}
var to_rids = to?reverseId(to,my_sex):[''];
to_rids.forEach(function(to_r){
var selector = (to_r?','+to_r:'')+(from?','+from:'');
result.push({
'selector':selector,
'sex':sex
});
});
});
to_rids = unique(to_rids);
if(toIsMale&&toIsFemale){
sex = -1;
}else if(toIsMale){
sex = 1;
}else if(toIsFemale){
sex = 0;
}
}else{
to_rids = [''];
}
// console.log('[from_ids]',from_ids,'to_rids',to_rids);
var from_selector = from_ids.length>1?'['+from_ids.join('|')+']':from_ids[0];
var to_selector = to_rids.length>1?'['+to_rids.join('|')+']':to_rids[0];
return {
'selector':(to?','+to_selector:'')+(from?','+from_selector:''),
'sex':sex
};
});
return result;
};
// 选择器转ID
@ -230,9 +342,9 @@ export function selector2id(selector,sex){
sex = 0;
}
}else if(sex==1&&selector.match(/^,[h0]/)){
return false;
return [];
}else if(sex==0&&selector.match(/^,[w1]/)){
return false;
return [];
}
// console.log('[selector]',selector);
var getId = function(selector,sex){
@ -242,8 +354,8 @@ export function selector2id(selector,sex){
if(sex>-1&&selector.indexOf(',1')==-1&&selector.indexOf(',0')==-1){
selector = ','+sex+selector;
}
if(selector.match(/,[mwd0](&[ol])?,w|,[hfs1](&[ol])?,h/)){ //同志关系去除
return false;
if(selector.match(/,[mwd0](&[ol\d]+)?,w|,[hfs1](&[ol\d]+)?,h/)){ //同志关系去除
return [];
}
var s='';
if(!hash[selector]){
@ -260,7 +372,7 @@ export function selector2id(selector,sex){
}
}
}while(s!=selector);
if(selector.match(/,[mwd0](&[ol])?,w|,[hfs1](&[ol])?,h/)){ //同志关系去除
if(selector.match(/,[mwd0](&[ol\d+])?,w|,[hfs1](&[ol\d]+)?,h/)){ //同志关系去除
return false;
}
selector = selector.replace(/,[01]/,'').substr(1); //去前面逗号和性别信息
@ -294,7 +406,7 @@ export function reverseId(id,sex){
age = '&o';
}
if(id){
id = id.replace(/&[ol]/g,'');
id = id.replace(/&[ol\d+]/g,'');
//性别判断
if(sex<0){
if(id.match(/^w/)){
@ -310,12 +422,9 @@ export function reverseId(id,sex){
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 g = 0;
var gMap = {'f':1,'m':1,'s':-1,'d':-1};
arr.forEach(function(r){
g += gMap[r]||0;
});
return arr.join(',')+(g?'':age);
var r_id = arr.join(',');
var gen = getGen(r_id);
return r_id +(gen?'':age);
};
if(sex<0){
result.push(doing(1));
@ -353,26 +462,44 @@ export function getItemsById(id){
}
return res;
};
if(_data[id]){ // 直接匹配称呼
items.push(_data[id][0]);
}else{
// 对排序进行处理
while(id.match(/&\d+/)){
var num = id.match(/&([\d]+)/)[1];
var zh = number2zh(num);
id = id.replace(/&\d+/,'');
if(_data[id]){
var item = '';
_data[id].forEach(function(name){
if(!item&&name.indexOf('几')>-1){
item = name.replace('几',zh);
}
});
if(!item){
item = _data[id][0].match(/^[大小]/)?_data[id][0].replace(/^[大小]/,zh):zh+_data[id][0];
}
items.push(item);
break;
}
}
// 直接匹配称呼
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));
}
}
// 忽略年龄条件查找
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;
};
@ -394,21 +521,25 @@ export function getChainById(id){
export function getPairsByIds(id1,id2){
var result = [];
var result_r = [];
id1 = id1.replace(/&\d+/,'');
id2 = id2.replace(/&\d+/,'');
var id1_r = id1.replace(/([ol])([bs])/,'x$2');
var id2_r = id2.replace(/([ol])([bs])/,'x$2');
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(/&[o|l]/,'').replace(/[o|l]b/,'xb').replace(/[o|l]s/,'xs');
return selector.replace(/&[ol\d]+/,'').replace(/([ol])([bs])/,'x$2');
});
var list2_r = list2.map(function(selector){
return selector.replace(/&[o|l]/,'').replace(/[o|l]b/,'xb').replace(/[o|l]s/,'xs');
return selector.replace(/&[ol\d]+/,'').replace(/([ol])([bs])/,'x$2');
});
if(list1.indexOf(id1)>-1&&list2.indexOf(id2)>-1||list1.indexOf(id2)>-1&&list2.indexOf(id1)>-1){
result.push(_pair[key][0]);
}
if(list1_r.indexOf(id1)>-1&&list2_r.indexOf(id2)>-1||list1_r.indexOf(id2)>-1&&list2_r.indexOf(id1)>-1){
if(list1_r.indexOf(id1_r)>-1&&list2_r.indexOf(id2_r)>-1||list1_r.indexOf(id2_r)>-1&&list2_r.indexOf(id1_r)>-1){
result_r.push(_pair[key][0]);
}
}

View File

@ -29,66 +29,67 @@ var relationship = function (parameter){
if(!to_selectors.length){
to_selectors = [''];
}
// console.log('[selectors]',from_selectors,to_selectors);
var result = []; //匹配结果
from_selectors.forEach(function(from){
to_selectors.forEach(function(to){
var data = mergeSelector({
from:from,
to:to,
from_selectors.forEach(function(from_selector){
to_selectors.forEach(function(to_selector){
var list = mergeSelector({
from:from_selector,
to:to_selector,
sex:options.sex,
optimal:options.optimal
});
// console.log('[data]',from,to,data);
var ids = data?selector2id(data['selector'],data['sex']):null;
// 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,data['sex']);
if(id.match(/([fhs1](&[ol])?|[olx]b)$/)){
sex = 1;
}else{
sex = 0;
list.forEach(function(data){
// console.log('[data]',from_selector,to_selector,data);
var ids = data?selector2id(data['selector'],data['sex']):null;
// 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])?|[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(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);
if(pairs.length){
result = result.concat(pairs);
}
});
}else{
temps.forEach(function(id){
var items = getItemsById(id);
if(!items.length){
items = getItemsById(sex+','+id);
}
if(items.length){
result = result.concat(items);
}
});
}
});
}
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);
if(pairs.length){
result = result.concat(pairs);
}
});
}else{
temps.forEach(function(id){
var items = getItemsById(id);
if(!items.length){
items = getItemsById(sex+','+id);
}
if(items.length){
result = result.concat(items);
}
});
}
});
}
});
});
});
return unique(result);

View File

@ -3,30 +3,35 @@ var test = require('tape');
var relationship = require('..');
test('relationship.js show to be tested', function (t) {
// TODO
t.deepEqual(relationship({text:'儿子的爸爸的妈妈',sex:1}),['妈妈']);
t.deepEqual(relationship({text:'爱人',sex:1}),['老婆']);
t.deepEqual(relationship({text:'爱人的爱人',sex:1}),['自己']);
t.deepEqual(relationship({text:'老婆的爱人',sex:1}),['自己']);
t.deepEqual(relationship({text:'老婆的老公',sex:1}),['自己']);
t.deepEqual(relationship({text:'老婆的外孙的姥爷',sex:1}),['自己']);
t.deepEqual(relationship({text:'表姐的哥哥',sex:1}),['姑表哥','舅表哥']);
t.deepEqual(relationship({text:'表姐的妹妹',sex:1}),['姑表姐','姑表妹','舅表姐','舅表妹']);
t.deepEqual(relationship({text:'弟弟的表哥',sex:1}),['姑表哥','姑表弟','舅表哥','舅表弟']);
t.deepEqual(relationship({text:'老公的老婆的儿子的爸爸',sex:0}),['老公']);
t.deepEqual(relationship({text:'哥哥的弟弟的爸爸的儿子',sex:1}),['哥哥','弟弟','自己']);
t.deepEqual(relationship({text:'爸爸的舅舅',sex:0,reverse:true}),['甥孙女']);
t.deepEqual(relationship({text:'舅爷爷',type:'chain'}),['爸爸的妈妈的兄弟']);
t.deepEqual(relationship({text:'堂兄弟的孩子',sex:1}),['堂侄','堂侄女']);
t.deepEqual(relationship({text:'岳母',target:'女儿',reverse:true}),['外孙女']);
t.deepEqual(relationship({text:'姑妈',target:'舅妈',reverse:true}),['兄弟眷兄妇','兄弟眷弟妇']);
t.deepEqual(relationship({text:'舅妈',target:'女儿',reverse:true}),['姑甥孙女','姑甥外孙女']);
t.deepEqual(relationship({text:'老公的父母',target:'孩子'}),['爷爷','奶奶']);
t.deepEqual(relationship({text:'爸爸的哥哥的弟弟的儿子'}),['堂哥','堂弟','哥哥','弟弟','自己']);
t.deepEqual(relationship({text:'外婆',target:'女婿',reverse:true}),['外曾孙女婿','外曾外孙女婿']);
t.deepEqual(relationship({text:'我',target:'爸爸'}),['儿子','女儿']);
t.deepEqual(relationship({text:'爱人',target:'娘家侄子'}),['姑丈']);
t.deepEqual(relationship({text:'岳母的配偶的孩子的爸爸'}),['岳父']);
t.deepEqual(relationship({text:'舅妈',target:'外婆',type:'pair'}),['婆媳']);
t.end();
t.deepEqual(relationship({text:'儿子的爸爸的妈妈',sex:1}),['妈妈']);
t.deepEqual(relationship({text:'爱人',sex:1}),['老婆']);
t.deepEqual(relationship({text:'爱人的爱人',sex:1}),['自己']);
t.deepEqual(relationship({text:'老婆的爱人',sex:1}),['自己']);
t.deepEqual(relationship({text:'老婆的老公',sex:1}),['自己']);
t.deepEqual(relationship({text:'老婆的外孙的姥爷',sex:1}),['自己']);
t.deepEqual(relationship({text:'表姐的哥哥',sex:1}),['姑表哥','舅表哥']);
t.deepEqual(relationship({text:'表姐的妹妹',sex:1}),['姑表姐','姑表妹','舅表姐','舅表妹']);
t.deepEqual(relationship({text:'弟弟的表哥',sex:1}),['姑表哥','姑表弟','舅表哥','舅表弟']);
t.deepEqual(relationship({text:'老公的老婆的儿子的爸爸',sex:0}),['老公']);
t.deepEqual(relationship({text:'哥哥的弟弟的爸爸的儿子',sex:1}),['哥哥','弟弟','自己']);
t.deepEqual(relationship({text:'爸爸的舅舅',sex:0,reverse:true}),['甥孙女']);
t.deepEqual(relationship({text:'舅爷爷',type:'chain'}),['爸爸的妈妈的兄弟']);
t.deepEqual(relationship({text:'堂兄弟的孩子',sex:1}),['堂侄','堂侄女']);
t.deepEqual(relationship({text:'岳母',target:'女儿',reverse:true}),['外孙女']);
t.deepEqual(relationship({text:'姑妈',target:'舅妈',reverse:true}),['兄弟眷兄妇','兄弟眷弟妇']);
t.deepEqual(relationship({text:'舅妈',target:'女儿',reverse:true}),['姑甥孙女','姑甥外孙女']);
t.deepEqual(relationship({text:'老公的父母',target:'孩子'}),['爷爷','奶奶']);
t.deepEqual(relationship({text:'爸爸的哥哥的弟弟的儿子'}),['堂哥','堂弟','哥哥','弟弟','自己']);
t.deepEqual(relationship({text:'外婆',target:'女婿',reverse:true}),['外曾孙女婿','外曾外孙女婿']);
t.deepEqual(relationship({text:'我',target:'爸爸'}),['儿子','女儿']);
t.deepEqual(relationship({text:'爱人',target:'娘家侄子'}),['姑丈']);
t.deepEqual(relationship({text:'岳母的配偶的孩子的爸爸'}),['岳父']);
t.deepEqual(relationship({text:'舅妈',target:'外婆',type:'pair'}),['婆媳']);
t.deepEqual(relationship({text:'妈妈的二哥'}),['二舅']);
t.deepEqual(relationship({text:'爸爸的二哥'}),['二伯']);
t.deepEqual(relationship({text:'二舅妈',target:'二舅',type:'pair'}),['夫妻']);
t.deepEqual(relationship({text:'二舅妈',target:'大舅',type:'pair'}),['叔嫂']);
t.deepEqual(relationship({text:'二舅妈',target:'三舅'}),['二嫂']);
t.deepEqual(relationship({text:'爸爸的二爸'}),['二爷爷']);
t.end();
});

View File

@ -4,12 +4,17 @@ const TerserJSPlugin = require('terser-webpack-plugin');
const pkg = require('./package');
var repository = pkg.repository.url.replace(/(.+)(:\/\/.+)\.git$/,'https$2');
var copyright = `${pkg.officialName} v${pkg.version} - ${pkg.description}
var date = (new Date()).toISOString().substr(0,10);
var copyright = `${pkg.name} v${pkg.version}
${pkg.description}
${pkg.homepage}
Copyright (c) 2016-present, ${pkg.author}
Released under the ${pkg.license} License.
${repository}/`;
${repository}
Released on: ${date}`;
module.exports = {
mode: 'production',