Help us understand the problem. What is going on with this article?

目からウロコ!Node-REDのデザインパターン10選

More than 1 year has passed since last update.

私がNode-REDを使い始めて4カ月が経ちました。開発をしていると、Node-REDには単にノードを横に繋いでゆくだけではなく、ノードの接続関係を活用したデザインパターンが沢山あることに気が付きました。

本記事では、Node-REDを今まで以上に活用できるデザインパターン10個を、ご紹介します。最後のソースコードは、IBM Cloud上のNode-REDはもちろん、ローカルPCにインストールしたNode-REDでも動作しますので、貼り付けて遊んでみてください。

Node-REDとは

Node-REDは、機能毎に用意されたノードをマウスで繋ぐ操作で、簡単にアプリケーションを作成できる開発環境です。当初はIoT向けに開発されましたが、ウェブアプリケーション開発等、幅広い用途で利用できます。最近では、SiemensのMindSphereで採用されたり、自作ノードの開発を支援するツールが開発されたりしており、様々な企業がNode-REDを活用しています。

デザインパターンとは

一般的にデザインパターンとは、Java等のオブジェクト指向言語を使いこなしてゆくと辿り着く、開発や変更の効率が良い設計パターンを指します。学生の時、興味深いパターンが何個か学び、特にMediatorやSingletonパターンは目から鱗でした。

Node-REDにおけるデザインパターン

Node-REDは、複雑な処理をカプセル化したノードが沢山用意されているため、ノードを繫ぐだけで簡単に一連の処理を実現できます。しかし、ノードを一方向に繋ぐのみでは、Node-REDの利点を活用しきれていないと考えます。
「処理のロジックを、ノードの接続関係で記述する」と視点を変えると、様々なデザインパターンのアイデアが沸いてきました。デザインパターンを用いると、一連の処理を理解しやすくなり、リリース後の修正も効率的に行えるようになります。

1. Store & Searchパターン

データの格納と検索を行うパターンです。

store_search_pattern.png

Node-REDは、IoT端末から受け取ったデータの処理向けに開発されたため、Store & Searchパターンは一番メジャーなパターンであると思います。
Storeパターンは、IoT端末等から取得したデータをデータベースに格納します。この時、JavaScriptを記述するノードを介して、格納するデータを選択したり、データを格納する列名を指定したりできます。
Searchパターンは、Storeパターンを用いて格納したデータを検索するパターンです。

2. UI & APIパターン

ブラウザ上でAPI問合せに用いる入力値を受け付け、APIを問合せた結果を表示するパターンです。

ui_api_pattern.png

UIパターンは、入力フォーム表示用処理、API問合せ結果表示用処理の2つの処理で構成されています。入力フォームのHTMLは、ブラウザ上でユーザから受け取った値をGETのパラメータとして、API問合せ結果表示用処理に引き継ぎます。API問合せ結果表示用処理は、パラメータの値を用いてウェブAPIを問合せ、その結果を表示用HTMLに組み込んで出力します。UIパターンは、ウェブAPIを問合せるUIを作成したい時に覚えておくと便利です。
APIパターンは、Node-RED上で扱うデータを、ウェブAPIとして問合せできるようにするためのパターンです。処理をウェブAPIとして作成しておくと、UIパターンからの問合せはもちろん、他の開発言語で開発したウェブアプリケーションからNode-RED上の処理を呼び出すことが容易となります。例えば、JavaのUI開発フレームワークVaadinでUIを開発し、内部ロジックはNode-REDでウェブAPIとして開発するという手法は、とても開発効率が良くオススメです。

3. Timeoutパターン

ノードの処理に時間がかかった場合、タイムアウトさせるパターンです。

timeout_pattern.png

Node-REDでDBやウェブAPIに問合せた際、応答が返って来ず、処理が進まないことがあります。この現象は、ウェブアプリケーションの際に致命的です。もし処理が終端のHTTP応答ノードまで到達しなかった場合、ユーザのブラウザはローディング状態になってしまい、ユーザは長時間待たされてしまいます。その時は、Timeoutパターンを用いて、指定秒数でタイムアウトし、「タイムアウトしました」というエラーを返す方が、ユーザに親切です。

4. whileパターン

ノードの接続のみで、while文を実現するパターンです。

while_pattern.png

Java等でwhile文を用いる場合は、変数i=0で初期化、条件文でループ回数指定、i++でインクリメントという3つの手順を行います。Node-REDにおけるwhileパターンは、同様の手順を行う初期化ノード、条件文ノード、インクリメントノードの3ノードから構成されます。whileパターンを用いると、ループ構造の把握が容易となり、リリース後にループ回数を変更する修正も迅速に行えます。ちなみにNode-REDにて、ループ処理を行う場合は、大抵8の字型の接続となりますので、すぐにループ処理を見つけることができます。

5. Sequenceパターン

複数のノードから得た処理結果を、集計するパターンです。

sequence_pattern.png

処理ノードはmsg.payloadを介して1つの値を出力すると、設計がシンプルとなります。しかし、複数のノードから取得した値を集計したい場合、単純にノードを横に繫いでしまうととmsg.payloadの値は上書きされてしまいます。Sequenceパターンでは、ノードからmsg.payloadを介して受け取った値を一旦、msg.tmp等の別変数に退避しておき、後続のノードがmsg.payloadに値を格納できるようにします。ノードから値を受け取る処理が全て終了した後、別変数に退避しておいた値を呼び出すことで、集計処理を実現します。

6. Aggregatorパターン

Sequenceパターンと同じく、複数のノードから得た処理結果を、集計するパターンです。

aggregator_pattern.png

Sequenceパターンは、ノードを横に繋いでいくのみであるため、処理ノードか、値を別変数に退避するノードかをノードの接続を見ただけでは、すぐ識別できません。Aggregatorパターンでは、集計ノードへ2つのノードが直接値を渡しているため、ノードの接続を見るだけで直観的に処理を把握できます。また、別の利点として、複数のウェブAPIに問合せた結果を集計するようなケースにて、並列してウェブAPIへリクエストできるため、処理時間を短縮できる特徴もあります。

7. Separatorパターン

1つのノードから2つの異なる値を出力するパターンです。

separator_pattern.png

Aggregatorパターンは「2入力」を実現するパターンであるのに対し、Separatorパターンは「2出力」を実現するパターンです。JavaScriptを記述するノードにて、サイズ2の配列をreturnし、出力数を指定するのみで実現できます。

8. MapReduceパターン

SeparatorパターンとAggregatorパターンを組み合わせて、MapReduceの処理を実現するパターンです。

mapreduce_pattern.png

Map処理は、Separatorパターンを用いて記述します。Map処理を行うノードは、入力値に対してWordCount等の処理を行い、Keyを基にKey-Valueペアの出力先を決定します。一方、Reduce処理は、Aggregatorパターンを用いて記述します。Reduce処理を行うノードは、事前に指定したMap数分の入力が来た後、同じKeyを持つValueのデータに対して集計等の処理を行います。Java等でMapReduce処理を記述すると、多重ループ等が原因で複雑になりがちですが、Node-REDではMapReduceの処理フローをノードの接続としてグラフィカルに記述できるため、簡単に作成でき、理解も容易です。

9. Matcherパターン

ノードのネットワーク構造を探索して、条件に一致するか判定するパターンです。

matcher_pattern.png

JavaScriptを記述するノードは、値をreturnしないと後続ノードの処理を実行しないという動きをします。Matcherパターンの条件ノードは、この特徴を生かし、入力値がノードの条件を満たす場合のみ、次のノードに処理を引き継ぎます。Matcherパターンでは、処理全体として満たしたい条件を、条件ノードのネットワーク構造として作成しておきます。判定したいデータを入力すると、そのネットワーク構造を探索し、ネットワーク構造から値が出てきた場合、条件に一致していることが分かります。
図の例では、Matcherパターンを用いて、入力した英文の文型を判定しています。内部では、品詞を判定する条件ノードから成るネットワーク構造を通過させることで、SV、SVC、SVO、SVOO、SVOCのどの文型に該当するかを判定しています。この処理は一度、品詞を判定するノードを作成しておけば、リリース後に品詞の並びを変える必要があっても、ノード接続を変える操作だけで修正が完結します。Node-REDは、iPadやAndroidタブレットでノードの接続を変更できるため、例えば通勤電車の中等、どこでも修正作業が行えます。

10. Stateパターン

状態遷移を扱うパターンです。

state_pattern.png

Stateパターンは、状態を表す状態ノードと、遷移先を表すSwitchノードから構成されます。状態ノードは、その状態に必要な処理を行い、Switchノードに判定したい値を引き継ぎます。その後、Switchノードは引き継いだ値の内容に従い判定し、次の状態ノードへ処理を移します。Java等で状態遷移を記述する場合は、状態遷移表を活用する等の方法を用いますが、コードから遷移の全体像を理解するは困難です。Node-REDを用いることで、状態の遷移が一目瞭然となります。

最後に

本記事を通して、新たな発見が得られれば幸いです。面白い他のデザインパターンや、もっと良いコードに気づいた方は、ご連絡ください。皆で議論し、新たなデザインパターンを見つけてゆけたら、良いなと考えています。

※本デザインパターンの内容は、RedConnectの技術サイトでも紹介されました。
※Store、Search、UI、Separatorパターンは、NECのNode-REDのドキュメントでも紹介されています。

ソースコード

Node-REDは、開発環境の右上メニュー->Import->Clipboardからソースコードを貼り付けることができます。

Store & Searchパターン

[{"id":"58f0c78.fa70f38","type":"comment","z":"d4f1d484.2b0e28","name":"Store pattern","info":"","x":139.67855072021484,"y":136.9643678665161,"wires":[]},{"id":"ac5df1bd.53a21","type":"function","z":"d4f1d484.2b0e28","name":"格納するデータを選択","func":"msg.payload = {DATA: new Date(msg.payload).toString()};\nreturn msg;","outputs":1,"noerr":0,"x":327.42858505249023,"y":182.9643850326538,"wires":[["bc71d473.438e28"]]},{"id":"bc71d473.438e28","type":"dashDB out","z":"d4f1d484.2b0e28","service":"dashDB-qu","table":"TMP","name":"DBへ格納","x":505.4285888671875,"y":182.96438694000244,"wires":[]},{"id":"4ad682a0.b5297c","type":"inject","z":"d4f1d484.2b0e28","name":"検索要求","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":152.1785888671875,"y":325.2143850326538,"wires":[["663e23c1.99c1dc"]]},{"id":"afccc742.503338","type":"inject","z":"d4f1d484.2b0e28","name":"入力データ","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":154.42858505249023,"y":182.9643850326538,"wires":[["ac5df1bd.53a21"]]},{"id":"663e23c1.99c1dc","type":"dashDB in","z":"d4f1d484.2b0e28","service":"dashDB-qu","query":"SELECT * FROM TMP;","params":"","name":"DBを検索","x":295.1785888671875,"y":325.2143850326538,"wires":[["1301aa90.ecfe55"]]},{"id":"1301aa90.ecfe55","type":"debug","z":"d4f1d484.2b0e28","name":"検索結果を出力","active":true,"console":"false","complete":"payload","x":462.17859649658203,"y":325.2143850326538,"wires":[]},{"id":"3b24f16a.c4db0e","type":"comment","z":"d4f1d484.2b0e28","name":"Search pattern","info":"","x":144.67858123779297,"y":276.96437549591064,"wires":[]},{"id":"9efbd918.610428","type":"comment","z":"d4f1d484.2b0e28","name":"↑格納したデータを検索","info":"","x":369.67859649658203,"y":366.5477056503296,"wires":[]},{"id":"42d56d7b.bd2a94","type":"comment","z":"d4f1d484.2b0e28","name":"↑IoT端末等からデータを取得","info":"","x":237.4285430908203,"y":225.46437644958496,"wires":[]},{"id":"d987c196.26784","type":"inject","z":"d4f1d484.2b0e28","name":"表削除","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":146.2499885559082,"y":89.39282989501953,"wires":[["7ab2ca59.854d34"]]},{"id":"7ab2ca59.854d34","type":"dashDB in","z":"d4f1d484.2b0e28","service":"dashDB-qu","query":"DROP TABLE TMP;","params":"","name":"DROP TABLE","x":294.2499885559082,"y":89.39282989501953,"wires":[["a0547bb4.5fab88"]]},{"id":"a0547bb4.5fab88","type":"debug","z":"d4f1d484.2b0e28","name":"[]が出力されれば成功","active":true,"console":"false","complete":"payload","x":500.2499885559082,"y":89.39282989501953,"wires":[]},{"id":"8bead6df.741528","type":"inject","z":"d4f1d484.2b0e28","name":"表作成","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":145,"y":42.14285659790039,"wires":[["3449d1ee.cbb62e"]]},{"id":"3449d1ee.cbb62e","type":"dashDB in","z":"d4f1d484.2b0e28","service":"dashDB-qu","query":"CREATE TABLE TMP (DATA VARCHAR(255));","params":"","name":"CREATE TABLE","x":300,"y":42.14285659790039,"wires":[["93dc73d3.6c239"]]},{"id":"93dc73d3.6c239","type":"debug","z":"d4f1d484.2b0e28","name":"[]が出力されれば成功","active":true,"console":"false","complete":"payload","x":499,"y":42.14285659790039,"wires":[]}]

UI & APIパターン

[{"id":"3675bb25.c98a44","type":"comment","z":"d4f1d484.2b0e28","name":"UI pattern","info":"","x":129.4008445739746,"y":410.96428298950195,"wires":[]},{"id":"9f7d159f.6082e8","type":"http in","z":"d4f1d484.2b0e28","name":"","url":"/output","method":"get","swaggerDoc":"","x":135.67858123779297,"y":539.1587057113647,"wires":[["15ee7da3.ea1182"]]},{"id":"15ee7da3.ea1182","type":"function","z":"d4f1d484.2b0e28","name":"API問合せ用URL作成","func":"msg.url = msg.req.host + \"/api?q=\" + encodeURI(msg.payload.q);\nreturn msg;","outputs":1,"noerr":0,"x":313.24999237060547,"y":539.2538747787476,"wires":[["b6619f87.499e6"]]},{"id":"b6619f87.499e6","type":"http request","z":"d4f1d484.2b0e28","name":"API問合せ","method":"GET","ret":"obj","url":"","x":488.53580474853516,"y":538.5872087478638,"wires":[["c58cb91a.3a7348"]]},{"id":"6260006b.9da","type":"http response","z":"d4f1d484.2b0e28","name":"HTTP応答","x":590.7738914489746,"y":636.6824054718018,"wires":[]},{"id":"c58cb91a.3a7348","type":"change","z":"d4f1d484.2b0e28","name":"headers削除","rules":[{"t":"delete","p":"headers"}],"action":"","property":"","from":"","to":"","reg":false,"x":299.96350479125977,"y":636.7300310134888,"wires":[["1e70abb0.e18f54"]]},{"id":"1e70abb0.e18f54","type":"template","z":"d4f1d484.2b0e28","name":"出力HTML","field":"payload","format":"html","template":"<HTML><BODY>\nテーブルの行数は{{payload.1}}です。\n</BODY></HTML>","x":448.6785888671875,"y":636.8253183364868,"wires":[["6260006b.9da"]]},{"id":"fbe35ede.041ca","type":"http response","z":"d4f1d484.2b0e28","name":"HTTP応答","x":485.9169235229492,"y":456.96418952941895,"wires":[]},{"id":"f2694ba7.0d96b8","type":"http in","z":"d4f1d484.2b0e28","name":"","url":"/input","method":"get","swaggerDoc":"","x":132.58342742919922,"y":456.964204788208,"wires":[["302a43fd.cfd5bc"]]},{"id":"302a43fd.cfd5bc","type":"template","z":"d4f1d484.2b0e28","name":"入力フォームHTML","field":"payload","format":"html","template":"<HTML><BODY><FORM method='GET' action='output'>\nテーブル名:<INPUT type='text' name='q' value='TMP'>\n<INPUT type='submit'>\n</FORM></BODY></HTML>","x":308.2501106262207,"y":456.6308391094208,"wires":[["fbe35ede.041ca"]]},{"id":"fc025f83.03fda","type":"http in","z":"d4f1d484.2b0e28","name":"","url":"/api","method":"get","swaggerDoc":"","x":128.0395851135254,"y":779.4920873641968,"wires":[["c132f98c.3ecd08"]]},{"id":"e3c106e6.1c3ef8","type":"http response","z":"d4f1d484.2b0e28","name":"HTTP応答","x":557.9286231994629,"y":779.2063293457031,"wires":[]},{"id":"43292e38.bcd6d","type":"comment","z":"d4f1d484.2b0e28","name":"API pattern","info":"","x":135.40087890625,"y":732.3809695243835,"wires":[]},{"id":"dda5c57a.225a38","type":"comment","z":"d4f1d484.2b0e28","name":"↓下のAPIに問合わせ、結果取得","info":"","x":533.6508865356445,"y":498.1310005187988,"wires":[]},{"id":"2ed4fa3d.d12b06","type":"comment","z":"d4f1d484.2b0e28","name":"API問合せでヘッダが書換わるため削除↑","info":"","x":221.1508331298828,"y":679.3809394836426,"wires":[]},{"id":"268a49c.fd975b6","type":"comment","z":"d4f1d484.2b0e28","name":"↓ブラウザ上で値(検索ワード等)を受付け、下のGET実行","info":"","x":462.40087890625,"y":414.7976396083832,"wires":[]},{"id":"8b1381be.74ec8","type":"comment","z":"d4f1d484.2b0e28","name":"↑API取得結果をブラウザ上に表示","info":"","x":526.4842071533203,"y":678.880937576294,"wires":[]},{"id":"b8e79c46.47186","type":"comment","z":"d4f1d484.2b0e28","name":"パラメータの値からAPI問合せ用URL作成↓","info":"","x":224.65087890625,"y":498.4643135070801,"wires":[]},{"id":"e4473af4.1bb8c8","type":"comment","z":"d4f1d484.2b0e28","name":"↑ユーザが入力した値を用いて検索","info":"","x":496.87316131591797,"y":821.4841232299805,"wires":[]},{"id":"c132f98c.3ecd08","type":"template","z":"d4f1d484.2b0e28","name":"SQL文作成","field":"payload","format":"handlebars","template":"SELECT COUNT(*) FROM {{payload.q}};","x":267.71427154541016,"y":779.4285669326782,"wires":[["e8426a37.17bd98"]]},{"id":"e8426a37.17bd98","type":"dashDB in","z":"d4f1d484.2b0e28","service":"dashDB-qu","query":"","params":"","name":"DBを検索","x":414.1508026123047,"y":778.8730506896973,"wires":[["e3c106e6.1c3ef8"]]}]

Timeoutパターン

[{"id":"efd2874f.102d78","type":"comment","z":"d4f1d484.2b0e28","name":"Timeout pattern","info":"","x":121,"y":991,"wires":[]},{"id":"55fe0f56.aa01f","type":"comment","z":"d4f1d484.2b0e28","name":"5秒以内に検索が完了したら、ブラウザ上に検索結果を表示↓","info":"","x":251.50000762939453,"y":1040.999979019165,"wires":[]},{"id":"9f162cbb.60e9d","type":"comment","z":"d4f1d484.2b0e28","name":"検索が5秒以上かかったら、ブラウザ上に「タイムアウトしました」と表示↑","info":"","x":286,"y":1269.8333740234375,"wires":[]},{"id":"1cc5725.fe33a8e","type":"http in","z":"d4f1d484.2b0e28","name":"","url":"/output","method":"get","swaggerDoc":"","x":114,"y":1088,"wires":[["ae6de02b.51922","570e59a7.a8f1a8"]]},{"id":"ae6de02b.51922","type":"function","z":"d4f1d484.2b0e28","name":"API問合せ用URL作成","func":"msg.url = msg.req.host + \"/api?q=\" + encodeURI(msg.payload.q);\nreturn msg;","outputs":1,"noerr":0,"x":291.5714111328125,"y":1088.0951690673828,"wires":[["c15452cb.3eabb"]]},{"id":"c15452cb.3eabb","type":"http request","z":"d4f1d484.2b0e28","name":"API問合せ","method":"GET","ret":"obj","url":"","x":466.8572235107422,"y":1087.428503036499,"wires":[["a1c844c3.5e37b8"]]},{"id":"3a14a3b7.c5eb5c","type":"http response","z":"d4f1d484.2b0e28","name":"HTTP応答","x":603.0953102111816,"y":1185.523699760437,"wires":[]},{"id":"a1c844c3.5e37b8","type":"change","z":"d4f1d484.2b0e28","name":"headers削除","rules":[{"t":"delete","p":"headers"}],"action":"","property":"","from":"","to":"","reg":false,"x":312.2849235534668,"y":1185.571325302124,"wires":[["43ea4055.bc15c"]]},{"id":"43ea4055.bc15c","type":"template","z":"d4f1d484.2b0e28","name":"出力HTML","field":"payload","format":"html","template":"<HTML><BODY>\nテーブルの行数は{{payload.1}}です。\n</BODY></HTML>","x":461.00000762939453,"y":1185.666612625122,"wires":[["3a14a3b7.c5eb5c"]]},{"id":"570e59a7.a8f1a8","type":"delay","z":"d4f1d484.2b0e28","name":"5秒間待機","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":248.32141876220703,"y":1228.8412942886353,"wires":[["4eb3d9c9.b14c28"]]},{"id":"4eb3d9c9.b14c28","type":"template","z":"d4f1d484.2b0e28","name":"タイムアウト表示HTML","field":"payload","format":"html","template":"<HTML><BODY>\nタイムアウトしました。\n</BODY></HTML>","x":428.32141876220703,"y":1228.8412942886353,"wires":[["3a14a3b7.c5eb5c"]]}]

whileパターン

[{"id":"7a1c913a.85e37","type":"template","z":"bb0998cf.44f668","name":"i=0","field":"i","format":"handlebars","template":"0","x":320,"y":3680,"wires":[["4047b441.bfb84c"]]},{"id":"4047b441.bfb84c","type":"switch","z":"bb0998cf.44f668","name":"i<4","property":"i","rules":[{"t":"lt","v":"4"},{"t":"else"}],"checkall":"true","outputs":2,"x":458,"y":3680,"wires":[["43f621ff.bc09e"],["dcb4322f.234bd"]]},{"id":"2a1ad095.d5e53","type":"function","z":"bb0998cf.44f668","name":"i++","func":"msg.i++;\n\nreturn msg;","outputs":1,"noerr":0,"x":564,"y":3585,"wires":[["4047b441.bfb84c"]]},{"id":"44dbc2cb.bb243c","type":"debug","z":"bb0998cf.44f668","name":"終了","active":true,"console":"false","complete":"payload","x":805,"y":3731,"wires":[]},{"id":"83af8aec.7c5078","type":"debug","z":"bb0998cf.44f668","name":"\"i回目\"を出力","active":true,"console":"false","complete":"payload","x":821.3999633789062,"y":3681.066650390625,"wires":[]},{"id":"822328ae.7ddcd8","type":"inject","z":"bb0998cf.44f668","name":"開始","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":201.89581298828125,"y":3679.888916015625,"wires":[["7a1c913a.85e37"]]},{"id":"a144ddbc.5ebb2","type":"comment","z":"bb0998cf.44f668","name":"while pattern","info":"","x":193.16665649414062,"y":3584.5556116104126,"wires":[]},{"id":"705c90e.f8fa37","type":"comment","z":"bb0998cf.44f668","name":"↓4回出力される","info":"","x":841.9999389648438,"y":3639.166615486145,"wires":[]},{"id":"8e84d3d2.717b3","type":"comment","z":"bb0998cf.44f668","name":"whileの条件文↑","info":"","x":410.66666412353516,"y":3720.6666402816772,"wires":[]},{"id":"56a6728c.a9598c","type":"comment","z":"bb0998cf.44f668","name":"インクリメントさせる値iを初期化↓","info":"","x":248.16665649414062,"y":3637.1667013168335,"wires":[]},{"id":"c68932e9.3976d","type":"comment","z":"bb0998cf.44f668","name":"←値iをインクリメント","info":"","x":736.4999694824219,"y":3585.3333740234375,"wires":[]},{"id":"dcb4322f.234bd","type":"template","z":"bb0998cf.44f668","name":"ループ後の処理","field":"payload","format":"handlebars","template":"ループ終了","x":613.2380752563477,"y":3730.869017601013,"wires":[["44dbc2cb.bb243c"]]},{"id":"43f621ff.bc09e","type":"template","z":"bb0998cf.44f668","name":"文字列\"i回目\"を生成","field":"payload","format":"handlebars","template":"{{i}}回目","x":624.9999694824219,"y":3681,"wires":[["83af8aec.7c5078","2a1ad095.d5e53"]]}]

Sequenceパターン

[{"id":"79318ef6.86ce7","type":"comment","name":"Sequence pattern","info":"","x":157.92858123779297,"y":1925.464274406433,"z":"d4f1d484.2b0e28","wires":[]},{"id":"98e06bb0.671f98","type":"function","name":"payload=451","func":"msg.payload = 451;\n\nreturn msg;","outputs":1,"noerr":0,"x":397.5952453613281,"y":1969.7976484298706,"z":"d4f1d484.2b0e28","wires":[["a589e119.5a762"]]},{"id":"11977bd5.ee6884","type":"function","name":"tmpとpayloadの合計算出","func":"msg.payload = msg.tmp + msg.payload;\n\nreturn msg;","outputs":1,"noerr":0,"x":592.5952453613281,"y":2052.7976484298706,"z":"d4f1d484.2b0e28","wires":[["2e654056.d19ac"]]},{"id":"2f1d71c.fd0e28e","type":"function","name":"payload=326","func":"msg.payload = 326;\n\nreturn msg;","outputs":1,"noerr":0,"x":397.5952453613281,"y":2052.7976484298706,"z":"d4f1d484.2b0e28","wires":[["11977bd5.ee6884"]]},{"id":"2e654056.d19ac","type":"debug","name":"777を出力","active":true,"console":"false","complete":"payload","x":777.5952453613281,"y":2052.7976484298706,"z":"d4f1d484.2b0e28","wires":[]},{"id":"8e353c9e.71cac","type":"inject","name":"2値の和を求める計算実行","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":205.59524536132812,"y":1969.7976484298706,"z":"d4f1d484.2b0e28","wires":[["98e06bb0.671f98"]]},{"id":"a589e119.5a762","type":"function","name":"tmp=payload","func":"msg.tmp = msg.payload;\n\nreturn msg;","outputs":1,"noerr":0,"x":556.5952453613281,"y":1969.7976484298706,"z":"d4f1d484.2b0e28","wires":[["2f1d71c.fd0e28e"]]},{"id":"bdfd8572.420278","type":"comment","name":"↓値を別の変数tmpへ退避","info":"","x":622.0951766967773,"y":1925.297646522522,"z":"d4f1d484.2b0e28","wires":[]},{"id":"f3c44263.0c3bc","type":"comment","name":"↓1つ目の値","info":"","x":394.09525299072266,"y":1926.1309614181519,"z":"d4f1d484.2b0e28","wires":[]},{"id":"9c2a1dca.63d5e","type":"comment","name":"↑2つ目の値","info":"","x":396.59523010253906,"y":2096.4642181396484,"z":"d4f1d484.2b0e28","wires":[]},{"id":"1cfe4562.e301bb","type":"comment","name":"↑退避した値tmpとpayloadの和を計算","info":"","x":692.0952377319336,"y":2096.464339733124,"z":"d4f1d484.2b0e28","wires":[]}]

Aggregatorパターン

[{"id":"fe9c117e.0163f","type":"comment","name":"Aggregator pattern","info":"","x":161.42858123779297,"y":2204.630959510803,"z":"d4f1d484.2b0e28","wires":[]},{"id":"9e0268f7.61fd98","type":"function","name":"payload=451","func":"msg.payload = 451;\n\nreturn msg;","outputs":1,"noerr":0,"x":432.26187896728516,"y":2288.131070137024,"z":"d4f1d484.2b0e28","wires":[["af493597.50b6c8"]]},{"id":"af493597.50b6c8","type":"function","name":"2つのpayloadの合計算出","func":"// 入力数を減らす\ncontext.global.n--;\n\n// msg.payloadのデータを格納\ncontext.global.data[context.global.n] = msg.payload;\n\n// 定義した入力数が来たら、集計処理を行い、msg.payloadを返す\nif (context.global.n === 0)\n{   // msg.payloadの合計値を算出\n    var sum = 0;\n    for (var i = 0; i < context.global.data.length; i++)\n    {\n        sum += context.global.data[i];\n    }\n    msg.payload = sum;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":640.2619247436523,"y":2311.131094932556,"z":"d4f1d484.2b0e28","wires":[["c2d9368.f3d26c8"]]},{"id":"72d62625.8d29d8","type":"function","name":"payload=326","func":"msg.payload = 326;\n\nreturn msg;","outputs":1,"noerr":0,"x":431.26190185546875,"y":2336.13108253479,"z":"d4f1d484.2b0e28","wires":[["af493597.50b6c8"]]},{"id":"c2d9368.f3d26c8","type":"debug","name":"777を出力","active":true,"console":"false","complete":"payload","x":822.2619018554688,"y":2312.13108253479,"z":"d4f1d484.2b0e28","wires":[]},{"id":"a8ee0b2c.5711f8","type":"function","name":"並列数=2","func":"context.global.n = 2;\ncontext.global.data = new Array(2);\n\nreturn msg;","outputs":1,"noerr":0,"x":271.26190185546875,"y":2313.13108253479,"z":"d4f1d484.2b0e28","wires":[["9e0268f7.61fd98","72d62625.8d29d8"]]},{"id":"39431b6c.c6bce4","type":"comment","name":"↓1つ目の値","info":"","x":431.0083923339844,"y":2249.7051458358765,"z":"d4f1d484.2b0e28","wires":[]},{"id":"1f653d.ffe09ac3","type":"inject","name":"2値の和を求める計算実行","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":205.31793975830078,"y":2249.8241748809814,"z":"d4f1d484.2b0e28","wires":[["a8ee0b2c.5711f8"]]},{"id":"1c32a960.e3cd57","type":"comment","name":"↑2つ目の値","info":"","x":429.8417434692383,"y":2376.7050580978394,"z":"d4f1d484.2b0e28","wires":[]},{"id":"f30cf9d4.0cf308","type":"comment","name":"グローバル変数に並列数を定義↑","info":"","x":201.7702865600586,"y":2356.2525358200073,"z":"d4f1d484.2b0e28","wires":[]},{"id":"bee9177f.4116e8","type":"comment","name":"↑並列数分の入力が来た後、和を計算","info":"","x":743.3417587280273,"y":2353.5384435653687,"z":"d4f1d484.2b0e28","wires":[]}]

Separatorパターン

[{"id":"1419e877.ebe618","type":"inject","name":"実行","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":155.0952377319336,"y":2485.79771900177,"z":"d4f1d484.2b0e28","wires":[["8f4d7d43.70b28"]]},{"id":"8f4d7d43.70b28","type":"function","name":"1つ目に451、2つ目に326を出力","func":"msg.payload = 451;\nvar msg2 = {};\nmsg2.payload = 326;\n\nreturn [msg, msg2];","outputs":"2","noerr":0,"x":349.0952377319336,"y":2485.79771900177,"z":"d4f1d484.2b0e28","wires":[["a69d939d.59627"],["ace2220e.531de"]]},{"id":"a69d939d.59627","type":"debug","name":"451を出力","active":true,"console":"false","complete":"payload","x":562.0952377319336,"y":2458.79771900177,"z":"d4f1d484.2b0e28","wires":[]},{"id":"ace2220e.531de","type":"debug","name":"326を出力","active":true,"console":"false","complete":"payload","x":560.0952377319336,"y":2511.79771900177,"z":"d4f1d484.2b0e28","wires":[]},{"id":"b1c243df.4e3dc","type":"comment","name":"Separator pattern","info":"","x":157.42858123779297,"y":2441.2976331710815,"z":"d4f1d484.2b0e28","wires":[]},{"id":"fba005.ff045ff8","type":"comment","name":"↑1ノードから異なる2値を出力","info":"","x":349.0083770751953,"y":2530.223530769348,"z":"d4f1d484.2b0e28","wires":[]}]

MapReduceパターン

[{"id":"42f22b03.bd0dd4","type":"inject","z":"d4f1d484.2b0e28","name":"WordCount実行","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":169.98413848876953,"y":2499.5753602981567,"wires":[["b48a3afc.4b75c8"]]},{"id":"1f8c6771.e07399","type":"function","z":"d4f1d484.2b0e28","name":"Map処理","func":"var input = msg.payload.toLowerCase()\n                       .replace( /\\.$/, \"\")\n                       .split(/ |, /);\n// Map\nvar key_value = [];\nfor (var i=0; i<input.length; i++)\n{\n    var key = input[i];\n    if (key in key_value)\n    {\n        key_value[key]++;\n    } else {\n        key_value[key] = 1;\n    }\n}\n\n// Shuffle\nvar key1_value = [];\nvar key2_value = [];\nfor (var key in key_value)\n{\n    if ('a'<=key[0] && key[0]<='m')\n    {\n        key1_value.push([key, key_value[key]]);\n    } else {\n        key2_value.push([key, key_value[key]]);\n    }\n}\n\nmsg.payload = key1_value;\nvar msg2 = {};\nmsg2.payload = key2_value;\nreturn [msg, msg2];","outputs":"2","noerr":0,"x":469.98413848876953,"y":2534.575316429138,"wires":[["9fe7f7de.601808"],["8582eef5.7a7d1"]]},{"id":"9fe7f7de.601808","type":"function","z":"d4f1d484.2b0e28","name":"Reduce処理","func":"// 入力数を減らす\ncontext.global.n1--;\n\n// msg.payloadのデータを格納\ncontext.global.data1[context.global.n1] = msg.payload;\n\n// 定義した入力数が来たら、集計処理を行い、msg.payloadを返す\nif (context.global.n1 === 0)\n{   // msg.payloadの合計値を算出\n    var tmp = [];\n    for (var i=0; i<context.global.data1.length; i++)\n    {\n        var input = context.global.data1[i];\n        for (var j=0; j<input.length; j++)\n        {\n            var key = input[j][0];\n            var value = input[j][1];\n            if (key in tmp)\n            {\n                tmp[key] += value;\n            } else {\n                tmp[key] = value;\n            }\n        }\n    }\n    \n    var output = [];\n    for (var key in tmp)\n    {\n        output.push([key, tmp[key]]);\n    }\n    msg.payload = output;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":677.9841384887695,"y":2549.575316429138,"wires":[["9c431c80.63bce"]]},{"id":"9c431c80.63bce","type":"debug","z":"d4f1d484.2b0e28","name":"結果出力","active":true,"console":"false","complete":"payload","x":817.9841384887695,"y":2549.575316429138,"wires":[]},{"id":"b48a3afc.4b75c8","type":"function","z":"d4f1d484.2b0e28","name":"Map数=3","func":"var map = 3; // Map数を定義\n\ncontext.global.n1 = map;\ncontext.global.data1 = new Array(map);\n\ncontext.global.n2 = map;\ncontext.global.data2 = new Array(map);\n\nreturn msg;","outputs":1,"noerr":0,"x":156.98413848876953,"y":2580.575316429138,"wires":[["b309b836.4cf648","3d3d88ef.c2c278","fe5a1ff0.01a5e"]]},{"id":"b309b836.4cf648","type":"template","z":"d4f1d484.2b0e28","name":"This is a pen.","field":"payload","format":"html","template":"This is a pen.","x":325.98413848876953,"y":2534.575316429138,"wires":[["1f8c6771.e07399"]]},{"id":"8582eef5.7a7d1","type":"function","z":"d4f1d484.2b0e28","name":"Reduce処理","func":"// 入力数を減らす\ncontext.global.n2--;\n\n// msg.payloadのデータを格納\ncontext.global.data2[context.global.n2] = msg.payload;\n\n// 定義した入力数が来たら、集計処理を行い、msg.payloadを返す\nif (context.global.n2 === 0)\n{   // msg.payloadの合計値を算出\n    var tmp = [];\n    for (var i=0; i<context.global.data2.length; i++)\n    {\n        var input = context.global.data2[i];\n        for (var j=0; j<input.length; j++)\n        {\n            var key = input[j][0];\n            var value = input[j][1];\n            if (key in tmp)\n            {\n                tmp[key] += value;\n            } else {\n                tmp[key] = value;\n            }\n        }\n    }\n    \n    var output = [];\n    for (var key in tmp)\n    {\n        output.push([key, tmp[key]]);\n    }\n    msg.payload = output;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":679.9841384887695,"y":2601.575316429138,"wires":[["1b1d3a66.e4e2c6"]]},{"id":"1b1d3a66.e4e2c6","type":"debug","z":"d4f1d484.2b0e28","name":"結果出力","active":true,"console":"false","complete":"payload","x":818.9841384887695,"y":2601.575316429138,"wires":[]},{"id":"b931daa2.46ce28","type":"function","z":"d4f1d484.2b0e28","name":"Map処理","func":"var input = msg.payload.toLowerCase()\n                       .replace( /\\.$/, \"\")\n                       .split(/ |, /);\n// Map\nvar key_value = [];\nfor (var i=0; i<input.length; i++)\n{\n    var key = input[i];\n    if (key in key_value)\n    {\n        key_value[key]++;\n    } else {\n        key_value[key] = 1;\n    }\n}\n\n// Shuffle\nvar key1_value = [];\nvar key2_value = [];\nfor (var key in key_value)\n{\n    if ('a'<=key[0] && key[0]<='m')\n    {\n        key1_value.push([key, key_value[key]]);\n    } else {\n        key2_value.push([key, key_value[key]]);\n    }\n}\n\nmsg.payload = key1_value;\nvar msg2 = {};\nmsg2.payload = key2_value;\nreturn [msg, msg2];","outputs":"2","noerr":0,"x":470.98413848876953,"y":2580.575316429138,"wires":[["9fe7f7de.601808"],["8582eef5.7a7d1"]]},{"id":"83ed63.ff7c12a","type":"function","z":"d4f1d484.2b0e28","name":"Map処理","func":"var input = msg.payload.toLowerCase()\n                       .replace( /\\.$/, \"\")\n                       .split(/ |, /);\n// Map\nvar key_value = [];\nfor (var i=0; i<input.length; i++)\n{\n    var key = input[i];\n    if (key in key_value)\n    {\n        key_value[key]++;\n    } else {\n        key_value[key] = 1;\n    }\n}\n\n// Shuffle\nvar key1_value = [];\nvar key2_value = [];\nfor (var key in key_value)\n{\n    if ('a'<=key[0] && key[0]<='m')\n    {\n        key1_value.push([key, key_value[key]]);\n    } else {\n        key2_value.push([key, key_value[key]]);\n    }\n}\n\nmsg.payload = key1_value;\nvar msg2 = {};\nmsg2.payload = key2_value;\nreturn [msg, msg2];","outputs":"2","noerr":0,"x":471.98413848876953,"y":2626.575316429138,"wires":[["9fe7f7de.601808"],["8582eef5.7a7d1"]]},{"id":"3d3d88ef.c2c278","type":"template","z":"d4f1d484.2b0e28","name":"Give me a pen.","field":"payload","format":"html","template":"Give me a pen.","x":320.98413848876953,"y":2580.575316429138,"wires":[["b931daa2.46ce28"]]},{"id":"fe5a1ff0.01a5e","type":"template","z":"d4f1d484.2b0e28","name":"This pen is small.","field":"payload","format":"html","template":"This pen is small.","x":313.98413848876953,"y":2626.575316429138,"wires":[["83ed63.ff7c12a"]]},{"id":"f78466af.087b98","type":"comment","z":"d4f1d484.2b0e28","name":"MapReduce pattern","info":"","x":156.98413848876953,"y":2455.575316429138,"wires":[]},{"id":"42607f4e.bd9f8","type":"comment","z":"d4f1d484.2b0e28","name":"Map数を定義↑","info":"","x":140.89732360839844,"y":2623.001223564148,"wires":[]},{"id":"c5857142.3a7a9","type":"comment","z":"d4f1d484.2b0e28","name":"↓処理対象の入力データ","info":"","x":394.06397247314453,"y":2493.001136779785,"wires":[]},{"id":"4f68dbe2.b09724","type":"comment","z":"d4f1d484.2b0e28","name":"↑単語をkey、出現回数をvalueとし、Reduce処理に渡す","info":"","x":628.3972625732422,"y":2668.426999092102,"wires":[]},{"id":"a8da3026.5725d","type":"comment","z":"d4f1d484.2b0e28","name":"↓同じ単語の出現回数の和を求める","info":"","x":766.5639495849609,"y":2507.093747138977,"wires":[]},{"id":"9a92b61d.656d48","type":"comment","z":"d4f1d484.2b0e28","name":"Map数分の入力後、","info":"","x":722.4841384887695,"y":2475.4919862747192,"wires":[]}]

Matcherパターン

[{"id":"7687ce5.f89783","type":"comment","z":"5e4dc05d.a1b24","name":"Matcher pattern","info":"","x":242.1428680419922,"y":1595,"wires":[]},{"id":"b6a262bc.495da","type":"inject","z":"5e4dc05d.a1b24","name":"The man walked.","topic":"","payload":"The man walked.","payloadType":"string","repeat":"","crontab":"","once":false,"x":268.9120903015137,"y":1671.5384359359741,"wires":[["1924ffc2.e6db"]]},{"id":"c7a58590.385a78","type":"function","z":"5e4dc05d.a1b24","name":"名詞","func":"var words = [\"man\", \"her\", \"he\", \"him\", \"e-mail\", \"book\", \"i\", \"we\", \"she\",\"this\", \"pen\", \"chocolate\", \"me\", \"ladder\", \"wall\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":696.1428375244141,"y":1651,"wires":[["1728a714.e8d759"]]},{"id":"1924ffc2.e6db","type":"function","z":"5e4dc05d.a1b24","name":"文字列を配列化","func":"msg.payload = msg.payload.toLowerCase()\n                         .replace( /\\.$/, \"\")\n                         .split(/ |, /);\nreturn msg;","outputs":1,"noerr":0,"x":468.1428680419922,"y":1595,"wires":[["c7a58590.385a78","c192fb64.3e6d08"]]},{"id":"dc6551e9.239ab","type":"inject","z":"5e4dc05d.a1b24","name":"He looks tired.","topic":"","payload":"He looks tired.","payloadType":"string","repeat":"","crontab":"","once":false,"x":263.3736763000488,"y":1729.0768766403198,"wires":[["1924ffc2.e6db"]]},{"id":"585038d7.a7afc8","type":"inject","z":"5e4dc05d.a1b24","name":"I bought a book.","topic":"","payload":"I bought a book.","payloadType":"string","repeat":"","crontab":"","once":false,"x":270.9121513366699,"y":1789.5385160446167,"wires":[["1924ffc2.e6db"]]},{"id":"f026e64.f0fd918","type":"function","z":"5e4dc05d.a1b24","name":"冠詞","func":"var words = [\"the\", \"a\", \"an\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":636.1428604125977,"y":1785.000012397766,"wires":[["379c9674.c8636a"]]},{"id":"1728a714.e8d759","type":"function","z":"5e4dc05d.a1b24","name":"動詞","func":"var words = [\"walked\", \"believe\", \"send\", \"bought\", \"looks\", \"is\", \"give\", \"leaning\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":490.14286041259766,"y":1727.000012397766,"wires":[["e7510579.18aef8","a88b7b5f.577488","f026e64.f0fd918","2808b0e2.d7f75","379c9674.c8636a","98b13a81.674ec8"]]},{"id":"e7510579.18aef8","type":"template","z":"5e4dc05d.a1b24","name":"第1文型SV","field":"payload2","format":"handlebars","template":"第1文型SV","x":969.1428985595703,"y":1669,"wires":[["ca202d62.35dfd"]]},{"id":"912cace1.6ed35","type":"template","z":"5e4dc05d.a1b24","name":"第2文型SVC","field":"payload2","format":"handlebars","template":"第2文型SVC","x":972.1428985595703,"y":1725,"wires":[["ca202d62.35dfd"]]},{"id":"a88b7b5f.577488","type":"function","z":"5e4dc05d.a1b24","name":"形容詞","func":"var words = [\"tall\", \"innocent\", \"tired\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":824.1428604125977,"y":1725.000012397766,"wires":[["912cace1.6ed35"]]},{"id":"95aa6b7c.6a5598","type":"inject","z":"5e4dc05d.a1b24","name":"I send her an e-mail.","topic":"","payload":"I send her an e-mail.","payloadType":"string","repeat":"","crontab":"","once":false,"x":284.47625255584717,"y":1848.8462619781494,"wires":[["1924ffc2.e6db"]]},{"id":"f96a1b74.0695e8","type":"inject","z":"5e4dc05d.a1b24","name":"I believe him innocent.","topic":"","payload":"I believe him innocent.","payloadType":"string","repeat":"","crontab":"","once":false,"x":291.6814155578613,"y":1904.4615726470947,"wires":[["1924ffc2.e6db"]]},{"id":"50b8bf36.af474","type":"template","z":"5e4dc05d.a1b24","name":"第3文型SVO","field":"payload2","format":"handlebars","template":"第3文型SVO","x":971.1428985595703,"y":1786,"wires":[["ca202d62.35dfd"]]},{"id":"43aedca2.bc5124","type":"template","z":"5e4dc05d.a1b24","name":"第4文型SVOO","field":"payload2","format":"handlebars","template":"第4文型SVOO","x":975.1428604125977,"y":1845.000012397766,"wires":[["ca202d62.35dfd"]]},{"id":"bef90a4e.4106f8","type":"template","z":"5e4dc05d.a1b24","name":"第5文型SVOC","field":"payload2","format":"handlebars","template":"第5文型SVOC","x":975.1428604125977,"y":1902.000012397766,"wires":[["ca202d62.35dfd"]]},{"id":"379c9674.c8636a","type":"function","z":"5e4dc05d.a1b24","name":"名詞","func":"var words = [\"man\", \"her\", \"he\", \"him\", \"e-mail\", \"book\", \"i\", \"we\", \"she\",\"this\", \"pen\", \"chocolate\", \"me\", \"ladder\", \"wall\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":824.1428604125977,"y":1786.000012397766,"wires":[["50b8bf36.af474"]]},{"id":"c192fb64.3e6d08","type":"function","z":"5e4dc05d.a1b24","name":"冠詞","func":"var words = [\"the\", \"a\", \"an\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":490.1428680419922,"y":1651,"wires":[["c7a58590.385a78"]]},{"id":"2808b0e2.d7f75","type":"function","z":"5e4dc05d.a1b24","name":"冠詞","func":"var words = [\"the\", \"a\", \"an\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":485.1428680419922,"y":1832,"wires":[["98b13a81.674ec8"]]},{"id":"98b13a81.674ec8","type":"function","z":"5e4dc05d.a1b24","name":"名詞","func":"var words = [\"man\", \"her\", \"he\", \"him\", \"e-mail\", \"book\", \"i\", \"we\", \"she\",\"this\", \"pen\", \"chocolate\", \"me\", \"ladder\", \"wall\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":634.1428604125977,"y":1833.000012397766,"wires":[["d11f2b1.f2ee0d8","6d503b99.92afc4","dbf80aa8.2407f8"]]},{"id":"d11f2b1.f2ee0d8","type":"function","z":"5e4dc05d.a1b24","name":"冠詞","func":"var words = [\"the\", \"a\", \"an\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":486.14286041259766,"y":1916.000012397766,"wires":[["6d503b99.92afc4"]]},{"id":"6d503b99.92afc4","type":"function","z":"5e4dc05d.a1b24","name":"名詞","func":"var words = [\"man\", \"her\", \"he\", \"him\", \"e-mail\", \"book\", \"i\", \"we\", \"she\",\"this\", \"pen\", \"chocolate\", \"me\", \"ladder\", \"wall\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":632.1428604125977,"y":1916.000012397766,"wires":[["43aedca2.bc5124"]]},{"id":"dbf80aa8.2407f8","type":"function","z":"5e4dc05d.a1b24","name":"形容詞","func":"var words = [\"tall\", \"innocent\", \"tired\"];\nvar tmp = msg.payload;\n\nif (words.indexOf(tmp[0]) >= 0)\n{\n    tmp.shift(); // 配列の先頭を削除\n    msg.payload = tmp;\n\n    return msg;\n}","outputs":1,"noerr":0,"x":834.1428375244141,"y":1902,"wires":[["bef90a4e.4106f8"]]},{"id":"72a20087.8d5e","type":"debug","z":"5e4dc05d.a1b24","name":"文型を出力","active":true,"console":"false","complete":"payload2","x":1178.0387725830078,"y":1850.5556640625,"wires":[]},{"id":"ca202d62.35dfd","type":"function","z":"5e4dc05d.a1b24","name":"全て探索済?","func":"var input = msg.payload;\n\nif (input.length === 0)\n{\n    return msg;    \n}\n","outputs":1,"noerr":0,"x":1169.884864807129,"y":1667.8633785247803,"wires":[["72a20087.8d5e"]]},{"id":"b949bd7e.46b64","type":"comment","z":"5e4dc05d.a1b24","name":"全ノードを探索している場合のみ、次のノードに渡す↓","info":"","x":1008.3464660644531,"y":1626.128547668457,"wires":[]},{"id":"caf9b247.35065","type":"comment","z":"5e4dc05d.a1b24","name":"↑先頭の単語の品詞が一致した場合、単語を削除し次のノードに渡す","info":"","x":648.8148651123047,"y":1957.1712636947632,"wires":[]},{"id":"7ff77a03.800884","type":"comment","z":"5e4dc05d.a1b24","name":"↑文型を判定する文字列","info":"","x":294.47298431396484,"y":1945.8632011413574,"wires":[]},{"id":"bdf91fcc.4206e","type":"comment","z":"5e4dc05d.a1b24","name":"↑判定した文型","info":"","x":1003.1908950805664,"y":1943.487506866455,"wires":[]}]

Stateパターン

[{"id":"3318e7e6.cce718","type":"switch","z":"5e4dc05d.a1b24","name":"1文字判定","property":"c","rules":[{"t":"regex","v":"\\+|\\-"},{"t":"regex","v":"\\d"},{"t":"eq","v":"."}],"checkall":"true","outputs":3,"x":443.6581726074219,"y":1120.6715087890625,"wires":[["1ac45ea9.e53ba1"],["3fd52c9e.c02ad4"],["5a961aa8.a569e4"]]},{"id":"8ffd81f1.70028","type":"inject","z":"5e4dc05d.a1b24","name":"0101","topic":"","payload":"0101","payloadType":"string","repeat":"","crontab":"","once":false,"x":236.30752563476562,"y":1119.4175281524658,"wires":[["1ac45ea9.e53ba1"]]},{"id":"1ac45ea9.e53ba1","type":"function","z":"5e4dc05d.a1b24","name":"状態a","func":"var input = msg.payload;\nvar len = input.length;\n\nif (msg.i == null)\n{\n    msg.i = 0;\n} else {\n    msg.i++;\n}\n\nmsg.c = input.charAt(msg.i);\nmsg.state = msg.i + \"回目: 状態=a, 文字=\" + msg.c;\n\nif (msg.i < len)\n{\n    return msg;\n}","outputs":1,"noerr":0,"x":400.71014404296875,"y":996.8587646484375,"wires":[["3318e7e6.cce718","ff5f8c7.f00a07"]]},{"id":"3fd52c9e.c02ad4","type":"function","z":"5e4dc05d.a1b24","name":"状態b","func":"var input = msg.payload;\nvar len = input.length;\n\nif (msg.i == null)\n{\n    msg.i = 0;\n} else {\n    msg.i++;\n}\n\nmsg.c = input.charAt(msg.i);\nmsg.state = msg.i + \"回目: 状態=b, 文字=\" + msg.c;\n\nif (msg.i < len)\n{\n    return msg;\n}","outputs":1,"noerr":0,"x":732.2685241699219,"y":997.4957275390625,"wires":[["a9be3bfd.5641c8","87629f53.789d6"]]},{"id":"b2e36234.4d1ca","type":"function","z":"5e4dc05d.a1b24","name":"状態c","func":"var input = msg.payload;\nvar len = input.length;\n\nif (msg.i == null)\n{\n    msg.i = 0;\n} else {\n    msg.i++;\n}\n\nmsg.c = input.charAt(msg.i);\nmsg.state = msg.i + \"回目: 状態=c, 文字=\" + msg.c;\n\nif (msg.i < len)\n{\n    return msg;\n}","outputs":1,"noerr":0,"x":488.1517028808594,"y":1217.9888916015625,"wires":[["fa4d1888.05b2e8","7f91b75.f806e48"]]},{"id":"119a07f.fee65f8","type":"function","z":"5e4dc05d.a1b24","name":"状態d","func":"var input = msg.payload;\nvar len = input.length;\n\nif (msg.i == null)\n{\n    msg.i = 0;\n} else {\n    msg.i++;\n}\n\nmsg.c = input.charAt(msg.i);\nmsg.state = msg.i + \"回目: 状態=d, 文字=\" + msg.c;\n\nif (msg.i < len)\n{\n    return msg;\n}","outputs":1,"noerr":0,"x":1012.4892883300781,"y":1084.2862548828125,"wires":[["c054e9a8.3fab18","e0f463be.1f0ba"]]},{"id":"7ff57b7c.800a84","type":"inject","z":"5e4dc05d.a1b24","name":"-1","topic":"","payload":"-1","payloadType":"string","repeat":"","crontab":"","once":false,"x":238.12570190429688,"y":1176.2861804962158,"wires":[["1ac45ea9.e53ba1"]]},{"id":"f993c065.066c4","type":"inject","z":"5e4dc05d.a1b24","name":"12.2","topic":"","payload":"12.2","payloadType":"string","repeat":"","crontab":"","once":false,"x":238.1257095336914,"y":1238.1046161651611,"wires":[["1ac45ea9.e53ba1"]]},{"id":"925dff15.6da2","type":"inject","z":"5e4dc05d.a1b24","name":"4.5.1","topic":"","payload":"4.5.1","payloadType":"string","repeat":"","crontab":"","once":false,"x":237.25555419921875,"y":1296.3514070510864,"wires":[["1ac45ea9.e53ba1"]]},{"id":"969fdc24.69602","type":"debug","z":"5e4dc05d.a1b24","name":"検査結果表示","active":true,"console":"false","complete":"payload","x":1146.7226257324219,"y":1337.4444580078125,"wires":[]},{"id":"5a961aa8.a569e4","type":"template","z":"5e4dc05d.a1b24","name":"不合格の文字列","field":"payload","format":"handlebars","template":"不合格の文字列","x":1155.2939147949219,"y":1286.7789306640625,"wires":[["969fdc24.69602"]]},{"id":"a9be3bfd.5641c8","type":"debug","z":"5e4dc05d.a1b24","name":"状態表示","active":true,"console":"false","complete":"state","x":888.6581115722656,"y":997.3380298614502,"wires":[]},{"id":"ff5f8c7.f00a07","type":"debug","z":"5e4dc05d.a1b24","name":"状態表示","active":true,"console":"false","complete":"state","x":553.9915161132812,"y":997.3385009765625,"wires":[]},{"id":"7f91b75.f806e48","type":"debug","z":"5e4dc05d.a1b24","name":"状態表示","active":true,"console":"false","complete":"state","x":637.6581726074219,"y":1218.3385009765625,"wires":[]},{"id":"87629f53.789d6","type":"switch","z":"5e4dc05d.a1b24","name":"1文字判定","property":"c","rules":[{"t":"regex","v":"\\+|\\-"},{"t":"regex","v":"\\d"},{"t":"eq","v":"."}],"checkall":"true","outputs":3,"x":754.6581726074219,"y":1120.6715259552002,"wires":[["5a961aa8.a569e4"],["3fd52c9e.c02ad4"],["b2e36234.4d1ca"]]},{"id":"fa4d1888.05b2e8","type":"switch","z":"5e4dc05d.a1b24","name":"1文字判定","property":"c","rules":[{"t":"regex","v":"\\+|\\-"},{"t":"regex","v":"\\d"},{"t":"eq","v":"."}],"checkall":"true","outputs":3,"x":533.6581726074219,"y":1338.6715087890625,"wires":[["5a961aa8.a569e4"],["119a07f.fee65f8"],["5a961aa8.a569e4"]]},{"id":"c054e9a8.3fab18","type":"switch","z":"5e4dc05d.a1b24","name":"1文字判定","property":"c","rules":[{"t":"regex","v":"\\+|\\-"},{"t":"regex","v":"\\d"},{"t":"eq","v":"."}],"checkall":"true","outputs":3,"x":1052.6581726074219,"y":1205.6715087890625,"wires":[["5a961aa8.a569e4"],["119a07f.fee65f8"],["5a961aa8.a569e4"]]},{"id":"e0f463be.1f0ba","type":"debug","z":"5e4dc05d.a1b24","name":"状態表示","active":true,"console":"false","complete":"state","x":1161.6581726074219,"y":1084.6715087890625,"wires":[]},{"id":"95c14cbc.6a3eb","type":"inject","z":"5e4dc05d.a1b24","name":"451+","topic":"","payload":"45+1","payloadType":"string","repeat":"","crontab":"","once":false,"x":235.65817260742188,"y":1354.6715087890625,"wires":[["1ac45ea9.e53ba1"]]},{"id":"58eb4834.a714b8","type":"comment","z":"5e4dc05d.a1b24","name":"State pattern","info":"","x":217,"y":953,"wires":[]},{"id":"b07b3995.4f84c8","type":"comment","z":"5e4dc05d.a1b24","name":"文字列を検査するための状態遷移","info":"","x":433.5,"y":952.4287109375,"wires":[]},{"id":"8f5096d8.70af68","type":"comment","z":"5e4dc05d.a1b24","name":"検査する文字列","info":"","x":227,"y":1074,"wires":[]}]
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした