質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

1671閲覧

javascriptの再帰関数について

kaiji0811

総合スコア7

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2016/07/26 17:12

編集2016/07/27 00:10

javascriptの再帰関数についてご質問です。

nodejsでwebページの解析をするため、htmlparserで生成したjsonの抽出機能を作成するため、
以下の関数を定義して呼び出したところ、
何故かtrees.length === 0の時も実行されてしまいます。
本来はarrのlength分だけ関数呼び出しを行いたい(今回で言うと三回)のですが、
実際にはarr.lengthが0のときも呼び出しが行われてしまうので、
datasがundefinedになってしまいます。

javascript

1 2// htmlparserで取得したデータのサンプルです。 3// 取得するデータはwebページにより異なり、順番やデータ数は変化するものとお考えください。 4var datas = [ 5 { 6 name: html, 7 children: [ 8 { 9 name: head, 10 children: [ 11 { 12 name: meta, 13 children: [{...},{...}, ...] 14 }, 15 { 16 name: title, 17 children: [{...},{...}, ...] 18 } 19 ] 20 }, 21 {...}, 22 {...}, 23 . 24 . 25 . 26 ] 27 } 28]; 29 30var arr = [ 'html', 'head', 'title' ], 31 result = dataExtracter(datas, arr, 'name'); 32 33function dataExtracter(datas, trees, param) { 34 if (!trees.length) return datas; 35 36 datas.map(function(item) { 37 38 if (item[param] === trees[0]) { 39 40 trees.shift(); 41 result = item.children; 42 43 if (trees.length > 0) { 44 dataExtracter(result, trees, param); 45 } 46 47 } 48 49 }); 50 51}

初めてプログラムで再帰関数を使用したのですが、
何か考え方が間違っているのでしょうか。R

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2016/07/26 17:49

このコードはブラウザで動かしているのでしょうか。デベロッパーツールなどでエラーを確認し、それを追記ください。また、「JSONのパースをするための抽出機能」とはどのような動作をするものでしょうか。具体的なデータを使って説明をお願いします。
kei344

2016/07/27 04:43

どういう結果を受け取りたいのかがわかりません。
kaiji0811

2016/07/27 13:47

nameがtitleの時のchildrenを取得したいのですが。わかりづらくて申し訳ありません。
kei344

2016/07/27 13:52

すいませんが、var datasと同じような形で質問文に追記していただけませんか?
guest

回答2

0

ベストアンサー

nameがtitleの時のchildrenを取得

どういう形で取得するかわからないので、とりあえず中身を配列に詰めるだけのコードです。
nodejs ってアロー関数とか使えたっけ・・・。

JavaScript

1var datas=[{name:'html',children:[{name:'head',children:[{name:'meta',children:[-3,-2,-1]},{name:'title',children:[0,1,2]}]},{name:'head',children:[{name:'meta',children:[3,4,5]},{name:'title',children:[6,7,8]}]}]}]; 2 3function seek( ar, tm ) { 4 if ( !tm ) { tm = []; } 5 return ar.reduce( ( prev, current )=> { 6 if ( current.hasOwnProperty( 'name' ) && current.hasOwnProperty( 'children' ) ) { 7 if ( current.name === 'title' ) { 8 tm.push( current.children ); 9 } else { 10 tm = seek( current.children, tm ); 11 } 12 } 13 return tm; 14 }, tm ); 15} 16console.log( seek( datas ) ); 17```**動くサンプル:**[https://jsfiddle.net/12h5j2rm/](https://jsfiddle.net/12h5j2rm/) 18 19--- 20 21**追記:** 22 23再起しないやつもついでに。 24 25```JavaScript 26var datas=[{name:'html',children:[{name:'head',children:[{name:'meta',children:[-3,-2,-1]},{name:'title',children:[0,1,2]}]},{name:'head',children:[{name:'meta',children:[3,4,5]},{name:'title',children:[6,7,8]}]}]}]; 27function seekWhile( ar ) { 28 var tm = [], crr; 29 while( ar.length ) { 30 crr = ar.shift(); 31 if ( crr.hasOwnProperty( 'name' ) && crr.hasOwnProperty( 'children' ) ) { 32 if ( crr.name === 'title' ) { 33 tm.push( crr.children ); 34 } else { 35 Array.prototype.push.apply( ar, crr.children ); 36 } 37 } 38 } 39 return tm; 40} 41console.log( 'seekWhile:', seekWhile( datas ) ); 42```**動くサンプル:**[https://jsfiddle.net/12h5j2rm/1/](https://jsfiddle.net/12h5j2rm/1/)

投稿2016/07/28 15:18

編集2016/07/28 19:08
kei344

総合スコア69400

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaiji0811

2016/07/29 15:20

ご丁寧にありがとうございます。非常に助かりました。
guest

0

JavaScript

1return dataExtracter(result, trees, param); //returnをつける

これでどうでしょう?

投稿2016/07/26 23:45

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaiji0811

2016/07/29 15:21

アドバイスありがとうございました。今回はkei344さんをベストアンサーとさせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問