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

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

新規登録して質問してみよう
ただいま回答率
85.50%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

3回答

2077閲覧

最適な再帰関数について(JSONからHTMLを作成する)

ssbb

総合スコア24

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2020/02/27 07:14

編集2020/02/27 07:28

前提・実現したいこと

下記のようなHTML構造を表した①JSONから②HTMLを生成しようとしていますが、
どのような再帰関数を書いて実現すれば良いか悩んでいます。(JSONはあくまで例であって「elemType」「children」変数はいくつも書く事が出来ます。)

可能であれば、JSX構文の回答だと嬉しいですが、JavaScriptでも構いません。
どなたか頭の柔らかい方ご教示をお願いします。。。

①JSON

JSON

1{ 2 "elemType":"div", 3 "children":[ 4 { 5 "elemType":"h1" 6 }, 7 { 8 "elemType":"div", 9 "children":[ 10 { 11 "elemType":"p" 12 }, 13 { 14 "elemType":"p" 15 } 16 ] 17 } 18 ], 19}

②HTML(変換結果)

HTML

1<div> 2 <h1></h1> 3 <div> 4 <p></p> 5 <p></p> 6 </div> 7</div>

###自身で書いたコード

tsx

1 2//関数② 3const getChild = (obj) => { 4 5 if (obj["children"] !== undefined) { 6 const elements = createElement(obj["children"]); 7 // ここで詰まり質問に至りました。。 8 } else { 9 return React.createElement(obj["elmType"], {}, null); 10 } 11}; 12 13//関数① 14const createElement = (obj) => { 15 if (obj.length !== undefined) { 16 return obj.map((obj2) => { 17 return getChild(obj2); 18 }); 19 } else { 20 return getChild(obj); 21 } 22}; 23 24const customFormatter = JSON.parse(CustomFormatter); //CustomFormatterがJSONになります 25const html = createElement(customFormatter);

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

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

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

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

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

kei344

2020/02/27 07:18

ご自身で試されたコードを質問文に追記し、「何」が「どのように」わからないのか、コードのどの部分で詰まっているのかなどを具体的に追記されたほうが回答が望めると思います。
miyabi_takatsuk

2020/02/27 07:20

ご自身で書いたコードはない感じですか? であれば、とにかく、まずは自分で書いてみてはいかがでしょうか? その上で、わからない部分、というのを質問にされたほうがいいかと。 現状だと、質問ではなく、作業依頼になってます。
ssbb

2020/02/27 07:29

kei344様 miyabi_takatsuk様 ご回答ありがとうございます。大変失礼いたしました。 自身で書いたコードを追加いたしました。
guest

回答3

0

ベストアンサー

今更かもしれませんが,JSX構文を用いるというのであれば次のように書けます.

jsx

1const createElement = elTree => { 2 const Tag = elTree.elemType; // 変数名の先頭大文字である必要あり 3 const children = elTree.children || []; 4 const childElements = children.map(c => createElement(c)); 5 6 return <Tag>{childElements}</Tag>; 7};

これをそのままrenderすると「childrenにkeyがない」というwarningが出るので,それを回避するには以下のようにできます.createElementを外から使用するときは引数keyを指定する必要はありません.

jsx

1const createElement = (elTree, key) => { 2 const Tag = elTree.elemType; 3 const children = elTree.children || []; 4 const childElements = children.map((c, i) => createElement(c, i)); 5 6 return <Tag key={key}>{childElements}</Tag>; 7};

投稿2020/02/27 09:32

編集2020/02/27 09:37
karamarimo

総合スコア2551

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

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

ssbb

2020/02/27 09:56

ご回答ありがとうございます。 こんな書き方があったんですね。。大変勉強になります。 今回JSX構文での書き方を求めてはいたため、恐縮ながらこちらをベストアンサーとさせて頂きます。
guest

0

頂いた回答内容を参考にJSX構文でも記述してみました。

JSX

1const customFormatter = JSON.parse(customFormatter); 2 3 4const createHTML = (obj) => { 5 6 var elements = null; 7 8 if (obj["children"] !== undefined) { 9 10 elements = obj["children"].map((objChild) => { 11 return createHTML(objChild); 12 }); 13 14 } 15 16 return React.createElement(obj["elmType"], {}, elements); 17} 18 19const html = createHTML(customFormatter);

投稿2020/02/27 08:52

ssbb

総合スコア24

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

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

0

javascript

1const customFormatter = JSON.parse(CustomFormatter); 2 3const JSONToElement = (elData, target) => { 4 // まず、elemTypeは必ずあるとして、DOM生成 5 const parent = document.createElement(elData.elemType); 6 // elData(オブジェクト単体)にchildrenが存在し、配列が空でない場合、forEachで走査して、再帰的に自身を実行する 7 if ( typeof elData.children !== 'undefined' && elData.children.length > 0) { 8 elData.children.forEach(data => { 9 // 第一引数には、JSONオブジェクト、第二引数には、子供を挿入したいDOMを渡す 10 JSONToElement(data, parent); 11 }); 12 } 13 14 if (target !== undefined && target !== null) { 15 // 挿入したいターゲットDOMがいれば、そのDOMに挿入する。 16 target.appendChild(parent); 17 } else { 18 // いなければ(初回の実行の要素がここにくる)DOMを返す 19 return parent; 20 } 21}; 22 23const html = JSONToElement(customFormatter);

投稿2020/02/27 07:47

miyabi_takatsuk

総合スコア9528

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

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

miyabi_takatsuk

2020/02/27 08:00

ポイントは同じような処理をしているところを再帰させることですね。
ssbb

2020/02/27 08:35

ありがとうございます! お蔭様で大分簡素化したコードで書く事が出来ました! 大変参考になります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問