前言
大家好我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心,通知大家一個好訊息:快過年啦!!!快過年啦!!!
但是通知大家一個壞訊息:過年了,你去走親戚,你知道應該怎麼稱呼你的親戚們嗎?比如你爸爸的哥哥的弟弟的兒子,你知道該怎麼稱呼嗎???哈哈哈哈,開個玩笑。但是,確實很多人去走親戚時,確實不知道怎麼稱呼自己的親戚,這時候就體現了程式設計的魅力了,畢竟著名的程式設計師「沃夏編德斯基」說過融入生活的程式設計才是好程式設計
普遍做法
做法
現在其實網上很多的做法都是這麼做的:稱謂 -> 直接關係 -> 稱謂,而所用的資料結構類似於下面這種:
{
"爸爸": {
"爸爸": "爺爺",
"媽媽": "奶奶",
"哥哥": "伯父",
"弟弟": "叔叔",
"姐姐": "姑媽",
"妹妹": "姑媽",
"丈夫": "未知",
"妻子": "媽媽",
"兒子": { "older": "哥哥", "middle": "我", "younger": "弟弟" },
"女兒": { "older": "姐姐", "middle": "我", "younger": "妹妹" }
}
}
缺點
其實上面的這種做法,是有很多缺點的:
- 1、無法直接查詢比如“舅媽的婆婆”這樣的複合關係
- 2、稱謂無法逆向查詢,比如:“表哥的媽媽”是“舅媽”、“姨媽”、還是“姑媽”?
- 3、資料結構臃腫,出現很多“未知”
正如上面的資料結構所見。。。“爸爸的丈夫”應該叫啥????”未知“。。。
- 4、無法相容多種稱呼,如“爸爸”也可以稱為“父親”、“爹地”
- 5、無法進行關係鏈的推理,比如:“舅媽”和我之間的關係鏈是什麼?
高階做法
語法
首先制定一套標準,推理親戚關係時都要以這套標準
關係
字母 | 關係 |
---|---|
f | 父 |
m | 母 |
h | 夫 |
w | 妻 |
s | 子 |
d | 女 |
xb | 兄弟 |
ob | 兄 |
lb | 弟 |
xs | 姐妹 |
os | 姐 |
ls | 妹 |
修飾符
修飾符 | 含義 | |
---|---|---|
1 | 男性 | |
0 | 女性 | |
&o | 年長 | |
&l | 年幼 | |
# | 隔斷 | |
[a\ | b] | 並列 |
資料結構
資料結構是這樣的鍵值對:直接關係鏈 -> 稱謂集合
舉個例子
- 'h':['老公','丈夫','先生','官人','男人','漢子','夫','夫君','相公','夫婿','愛人','老伴']
因為h
代表了夫
,而夫
的稱謂有以上幾種 - 'h,f':['公公','翁親','老公公']
因為h,f
代表了夫的父
,稱謂有以上幾種 - '[h,f|h,m]':['公婆']
因為[h,f|h,m]
意思是老公的爸爸和老公的媽媽
,那就是公婆
- '[f,xb,s&o|f,xb,s&l]':['堂兄弟']
因為[f,xb,s&o|f,xb,s&l]
意思是爸爸的兄弟的年長兒子和爸爸的兄弟的年幼兒子
,那就是堂兄弟
這樣在查詢關係的時候,只需要對直接關係鏈進行計算就好了,而不是對稱謂進行字典查詢
開搞
思路
舉個例子
- 1、當使用者輸入”舅媽的婆婆“,可以分解成”舅媽“和”婆婆“(前者的婆婆)
- 2、分解成的”舅媽“和”婆婆“,關係鏈分別是
m,xb,w
和h,m
,合併一起是m,xb,w,h,m
- 3、合併後的關係鏈出現冗餘,
w,h
是老婆的老公
,也就是自己,可簡化成m,xb,m
,且xb,m
是兄弟的媽媽
,也就是自己的媽媽,於是最後簡化成m,m
- 4、簡化後的關係鏈是一個
直接關係鏈
,可以通過鍵值對
去匹配查詢即可
實現
- 1、
鍵值對
,使用JSON
格式儲存,鍵值對形式查詢速度快 - 2、關係鏈簡化使用
正規表示式
,一次簡化兩層關係,直到不能簡化,但是簡化過程需考慮性別,比如:”兒子的媽媽“,當你是男性時代表了你的妻子,當你是女性的時候代表了你自己。這些都需要使用正規表示式
進行匹配,並且替換掉,這也是為什麼需要修飾符
的原因
relationship.js
使用方式
安裝
npm install relationship.js
使用
const relationship = require("relationship.js")
// 自定義模式
// 【關係鏈】f:父,m:母,h:夫,w:妻,s:子,d:女,xb:兄弟,ob:兄,lb:弟,xs:姐妹,os:姐,ls:妹
// 【修飾符】 1:男性,0:女性,&o:年長,&l:年幼,#:隔斷,[a|b]:並列
relationship.setMode('northern',{
'm,f': ['姥爺'],
'm,m': ['姥姥'],
'm,xb,s&o': ['表哥'],
'm,xb,s&l': ['表弟'],
})
var options = {
text: '', //輸入文字(稱謂的漢字表達,稱謂間用‘的’字分隔)
target: '', //針對物件:空表示自己
sex: 1, //自己的性別:0女性,1男性
type: 'default', //轉換型別:'default'計算稱謂,'chain'計算關係
reverse: false, //稱呼方式:true對方稱呼我,false我稱呼對方
mode: 'default' //模式選擇,可由使用者自定義
};
// 如:我應該叫外婆的哥哥什麼?
console.log(relationship({ text: '媽媽的媽媽的哥哥' })) // [ '外舅公' ]
// 如:七舅姥爺應該叫我什麼?
console.log(relationship({ text: '七舅姥爺', reverse: true, sex: 1 })) // [ '甥外孫' ]
// 如:舅公和我是什麼關係?
console.log(relationship({ text: '舅公', sex: 0, type: 'chain' }))
// [ '爸爸的媽媽的兄弟', '媽媽的媽媽的兄弟', '老公的媽媽的兄弟' ]
// 如:舅媽如何稱呼外婆?
console.log(relationship({ text: '外婆', target: '舅媽', sex: 1 })) // [ '婆婆' ]
親戚關係計算器-簡易版
配合 input、select、button
便可以簡單實現 親戚關係計算器-簡易版
了
// template
<div class="m-l-10 m-t-20">
<input v-model="options.text" />
<input v-model="options.target" />
<br />
<select v-model="options.sex">
<option :value="1">男</option>
<option :value="0">女</option>
</select>
<select v-model="options.type">
<option value="default">稱謂</option>
<option value="chain">關係</option>
</select>
<select v-model="options.reverse">
<option :value="false">正向</option>
<option :value="true">反向</option>
</select>
<br />
<button @click="computedRelationship">計算</button>
<span>{{result}}</span>
</div>
// data
options: {
text: "",
target: "",
sex: 1,
type: "default",
reverse: false,
mode: "default",
},
result: ''
import relationship from './relationship'
// methods
computedRelationship() {
console.log(this.options)
this.result = relationship(this.options)
},
親戚關係計算器-複雜版
參考文章
結語
我是林三心,一個熱心的前端菜鳥程式設計師。如果你上進,喜歡前端,想學習前端,那我們們可以交朋友,一起摸魚哈哈,摸魚群,加我請備註【思否】