用 JavaScript 對 JSON 進行模式匹配 (Part 1 - 設計)
在《從 if else 到 switch case 再到抽象》這篇文章里面說到,解決 if else 和 switch case 分支過多的一個方法,就是做一個專用的 dispatcher ,讓它來負責進行篩選與轉發。至于篩選條件的描述,模式匹配是一種很常見也很好用的方式。在 JavaScript 里面,用 JSON 來描述模式又是相當方便的事情,所以我們來做一個 JSON 模式匹配工具吧。
用例設計
作為一個 dispatcher ,我們只需要兩個方法: notify
和 capture
。一個最簡單的用例是這樣的:
1 Dispatcher.capture({
2 "status": 200,
3 "command": "message"
4 }, function(json) { /* display message */ });
5
6 Dispatcher.notify({
7 “status": 200,
8 "command": "message",
9 "content": {
10 "from": "user1",
11 "to": "user2",
12 "text": "hello"
13 }
14 });
2 "status": 200,
3 "command": "message"
4 }, function(json) { /* display message */ });
5
6 Dispatcher.notify({
7 “status": 200,
8 "command": "message",
9 "content": {
10 "from": "user1",
11 "to": "user2",
12 "text": "hello"
13 }
14 });
當然,只有局部的全等匹配是不夠的,我們還需要一些其他運算符。
1 Dispatcher.capture({
2 "value1$eq": "hello", /* equal */
3 "value2$ne": true, /* not equal */
4 "value3$lt": 0, /* less than */
5 "value4$lte: 1, /* less than or equal */
6 "value5$gt": 2, /* greater than */
7 "value6$gte": 3, /* greater than or equal */
8 "value7$in": [1, 3, 5, 7, 9], /* in */
9 "value8$nin": [2, 4, 6, 8, 10], /* not in */
10 "value9$all": [1, 2, 3, 4, 5], /* all */
11 "value10$ex": true, /* exists */
12 "value11$re": /^A.*/, /* regular expression */
13 "value12$ld": function(json) { return true; } /* lambda */
14 }, function(json) {});
15
16 Dispatcher.notify({
17 "value1": "hello",
18 "value2": false,
19 "value3": -1,
20 "value4": 1,
21 "value5": 3,
22 "value6": 3,
23 "value7": 5,
24 "value8": 5,
25 "value9": [1, 3, 5, 2, 4],
26 "value10": "hello",
27 "value11": "A13579",
28 "value12": "anything"
29 })
2 "value1$eq": "hello", /* equal */
3 "value2$ne": true, /* not equal */
4 "value3$lt": 0, /* less than */
5 "value4$lte: 1, /* less than or equal */
6 "value5$gt": 2, /* greater than */
7 "value6$gte": 3, /* greater than or equal */
8 "value7$in": [1, 3, 5, 7, 9], /* in */
9 "value8$nin": [2, 4, 6, 8, 10], /* not in */
10 "value9$all": [1, 2, 3, 4, 5], /* all */
11 "value10$ex": true, /* exists */
12 "value11$re": /^A.*/, /* regular expression */
13 "value12$ld": function(json) { return true; } /* lambda */
14 }, function(json) {});
15
16 Dispatcher.notify({
17 "value1": "hello",
18 "value2": false,
19 "value3": -1,
20 "value4": 1,
21 "value5": 3,
22 "value6": 3,
23 "value7": 5,
24 "value8": 5,
25 "value9": [1, 3, 5, 2, 4],
26 "value10": "hello",
27 "value11": "A13579",
28 "value12": "anything"
29 })
隨手寫下來一堆運算符,看起來實現會很復雜?其實不會有多復雜。在下一篇文章里面,我們會討論如何設計一個運算符接口,然后逐一實現這些運算符。如果你對此有興趣,歡迎在 Twitter 上關注我: @CatChen
全站熱搜