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

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

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

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

JavaScript

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

AngularJS

AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。

Q&A

解決済

8回答

22488閲覧

jsonファイルのメリット

退会済みユーザー

退会済みユーザー

総合スコア0

JSON

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

JavaScript

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

AngularJS

AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。

0グッド

3クリップ

投稿2017/04/10 15:08

最近AngularJSを勉強し始めたのですが、調べ物をしているとデータを表示する時にjsonファイルを利用していることが多く見受けられるのですが、なぜjsonなのでしょう。
javascriptの配列ではだめなのでしょうか。
もしくは配列を使うのも同じくらい一般的なのでしょうか。

例えば、大学の時間割のアプリを作りたいとします。
データ1つに対する項目として、
・曜日(0=mon,1=tue...)
・時限
・授業名
・先生の名前
・教室
などがあるとします。

配列の場合だと

javascript

1[1,2,"有機化学","山田","3-D"], 2[2,3,"無機化学","田中","1-B"]

のように非常に簡潔に書けますが、jsonだと

json

1 { 2 "week":1, 3 "time":2, 4 "subject":"有機化学", 5 "teacher":"山田", 6 "room":"3-D", 7 }, 8 { 9 "week":2, 10 "time":3, 11 "subject":"無機化学", 12 "teacher":"田中", 13 "room":"1-B", 14 }, 15

のようになりますが、10個くらいなら確かにコードも読みやすくていいと思うのですが、
これが100種類、200種類になるとデータ量が「無駄に」膨大になるしメリット薄い気がするんですが、実際どうなんでしょうか。
これはAnglarJSで使う場合の話です。

あと、少し話がそれますが、
ng-repeatは「全」項目をリピートしますが、実際「全」項目リピートってそんなに使うかなって思うんですが、あるとすれば例えば時限が「2」のもの曜日が「1」のもののように、膨大なデータの中から条件を決めて抽出するほうだと思います。
こういうときって普通にifなどで絞り込んでからng-repeatを用いるのですか?
質問ばかりで恐縮ですが、よろしくお願いします。

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

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

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

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

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

guest

回答8

0

そもそもJSONとは、'JavaScriptObjectNotation'の略で、「javascriptにおける'オブジェクト'を表現するための記法」のことです。すなわち、JSONデータ = javascriptにおけるオブジェクトです。

複数のデータをまとめる際に何故配列ではなくJSONを使うかというと、「その方が扱いやすいから」です。
例えば、質問内で提示されているデータの内容を表示するとき、配列とJSONではそれぞれ以下のようになるでしょう。

html

1<!-- 配列の場合 --> 2<h3>科目: {{ data[2] }}</p> 3<div> 4 <p>曜日: {{ data[1] }}</p> 5 <p>時限: {{ data[0] }}</p> 6</div> 7<div> 8 <p>教室: {{ data[4] }}</p> 9 <p>教員: {{ data[3] }}</p> 10</div> 11 12<!-- JSONの場合 --> 13<h3>科目: {{ data.subject }}</p> 14<div> 15 <p>曜日: {{ data.week }}</p> 16 <p>時限: {{ data.time }}</p> 17</div> 18<div> 19 <p>教室: {{ data.teacher }}</p> 20 <p>教員: {{ data.room }}</p> 21</div> 22

両者を比較してみて、いかがでしょうか。
配列の場合、2=科目、3=教員といった対応付けを全て覚えていないと、出力される内容が適切どうか把握できません。
一方、JSONの場合はデータそれぞれに名前を付けることができる=データに意味を持たせることができるので、人間に理解しやすくなります。上のJSONの例では、「教室」と「教員」が入れ替わっていることが一目瞭然ですね。
(配列の例では**「曜日」と「時限」も入れ替えてあります**が、すぐに気づけたでしょうか)

10個くらいなら確かにコードも読みやすくていいと思うのですが、

これが100種類、200種類になるとデータ量が「無駄に」膨大になるしメリット薄い気がするんですが、実際どうなんでしょうか。

配列の内容が100、200になった時、果たして100~200種類もの数字<=>データの対応付けを、を全て人間が覚えておけるでしょうか

一見すると配列の方が記述量が少なくお手軽に見えますが、配列はあくまで同じ種類のデータをまとめて管理するためのものです。種類の異なるデータを複数まとめて取り扱いたい場合は、JSON等のオブジェクトという形でまとめるのは、javascriptに限らない定跡だと思います。

膨大なデータの中から条件を決めて抽出する

こちらの質問について、私はAngularJSそのものにはあまり詳しくないのでAngularJSにズバリな機能があるかはわかりませんが、「条件を満たす値のみを配列から抽出する」という用途であれば、filterというメソッドがArrayオブジェクトに存在します。

javascript

1var data = [1, 2, 3, 4, 5, 6]; 2var odd = data.filter(function(val) { 3 return val % 2 !== 0; 4}); 5var even = data.filter(function(val) { 6 return val % 2 === 0; 7});

selectメソッドは、引数に渡されたコールバック関数を配列の要素ごとに実行します。そして、コールバック関数がtrueの値を返した要素のみをまとめた配列を新しく作ります。
上の例では、oddには[1, 3, 5]という配列が、evenには[2, 4, 6]という配列が入ります。
このような方法で値にフィルタリングをかけてから、ng-repeatに配列を渡すのはいかがでしょう。

投稿2017/04/10 15:54

philomagi

総合スコア267

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

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

退会済みユーザー

退会済みユーザー

2017/04/12 01:41

わかりやすい回答ありがとうございます。 少し語弊のあるような質問をしてしまい申し訳ないのですが、 「100種類、200種類」と言ったのは、 配列1行の中身[授業,先生,,,]の中身ではなく、 授業の種類 [], [], [], ,,, のことです。 つまり縦に100種類、200種類、と増えていくと、 「week」という文字列を100回、「time」という文字列を100回、「subject」という文字列を100回、、 とあまり意味のない文字列でデータを食ってしまうような気がするのです。 1行の中の項目は、week,time,subject,teacher,roomの5項目のみだとするとやはり配列の形の方が扱いやすい気がするのですが、どうでしょうか。
Everatch

2017/04/12 04:51

他のチームメイトが書いたコード、もしくは1年ぶりに自分のコードを改修するとき、 obj[3] と obj.teacher どっちのがわかりやすいですか? もしこのデータがいろんな場所で使っていたら? プログラミングにおいてもっとも重要なのは、いかに短く、簡潔にかけるかではありません、誰がいつ読んでも、そのコードの意味がわかりやすく書くことです。 ぶっちゃけ1年どころか、1ヶ月でも経てば配列の何番目に何があるのかはっきり覚えていられないと思いますよ。 プログラミングは"動けば良い"ものではない、このことを心がけながら勉強して行かないとですね! オススメの書籍: リーダブルコード amazon: http://amzn.asia/8zO1fQB
akabee

2017/04/12 05:08 編集

>「week」という文字列を100回、「time」という文字列を100回、「subject」という文字列を100回、、 とあまり意味のない文字列でデータを食ってしまうような気がするのです。 厳密には確かにご指摘のように多少は配列のほうが効率的に動作するかもしれませんが、内部的にはコンパイルを通して機械語で処理されますので、人間がコンピュータを制御するために記述したプログラミングコードが多少冗長になったとしても、それで劇的に処理速度やメモリ効率が落ちるということはありません。 0.0001秒を争うような開発をするのであればご指摘の通りかもしれませんが、そうではないのであれば、メンテナンス性を考慮したほうが一般的にはメリットが大きいということになります。
guest

0

この質問のポイントは配列とjsonの違いというより、配列と連想配列の違いな気がします。

javascript

1//配列版 2var hoge = [2,'無機化学']; 3//↓遠くのどこか 上の情報はスクロールしないとみえない 4week = hoge[0] 5subject = hoge[1] 6 7//連想配列版 8var hoge = {'week':2,'subject':'無機化学'}; 9//↓遠くのどこか 10week = hoge['week'] 11subject = hoge['subject']

これだとまだ大した違いはないですが、そこにtimeを入れることになったときは

javascript

1//配列版 2var hoge = [2,3,'無機化学']; 3//↓遠くのどこか 4week = hoge[0] 5time = hoge[1] // ←ここと 6subject = hoge[2] // ←ここを変える必要がある 7 8//連想配列版 9var hoge = {'week':2,'time':3,'subject':'無機化学'}; 10//↓遠くのどこか 11week = hoge['week'] 12time = hoge['time'] //←ここだけでいい 13subject = hoge['subject']

みたいになります。連想配列なら修正時にその要素が何番目になるのか、そして他の要素がどのようにずれるのかを考える必要がなくなるし、ラベルがそのままの意味なので勘違いによる間違えがでにくくなります。
配列だと予めしっかり設計していないと、1箇所変更するために100ファイル変更しないといけないとかもあり得るわけで、後でぐちゃぐちゃ変える可能性があるところでは使いにくいです。

jsonを使うと確かに配列よりも通信量は大きくなりますが、現代の通信環境ではそれほど大きな問題になるほどの差はなく、それよりもメンテナンス性の向上の方が価値があると考える人たちがjsonを採用したわけです。フレームワークであるAngularJSは、ちょっと通信量が多くなっても変化に強いことの方を選んだわけですね。

ここまでjsonびいきなことを書きましたが、配列の方がいい場合もあります。それは単一のテンプレートに当てはまる情報を大量に扱う場合です。カンマで文字列を繋げたCSVフォーマットとかがそれです。
通信量や通信時間やキャッシュするデータ量を気にするようなときに選びます。

要はそれぞれメリットデメリットがあるから、選択権がある人がそれらから最適と考えるものを選ぶわけです。その選択が良かったかそれともまずかったかは、使う各人が判断していいと思います。

投稿2017/04/10 16:24

oskbt

総合スコア1895

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

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

退会済みユーザー

退会済みユーザー

2017/04/12 01:43

わかりやすい回答ありがとうございました。 なるほど、確かにこれは連想配列と配列の違いな気がしますね。。
guest

0

こういうときって普通にifなどで絞り込んでからng-repeatを用いるのですか?

既に回答が出揃っていますので上記質問に対しAngularJSには上記を満たすようなFilterという機能があるということだけご紹介しておきます。
事前に絞り込まなくても、Filter機能を利用することでng-repeat使用時に任意の検索条件を指定することが可能です。

詳細はこちらのサイトが非常に分かり易いので参考にして下さい。

投稿2017/04/11 00:01

akabee

総合スコア1947

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

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

0

配列の要素のみだと、データの中身にどういうデータが格納されているのかが判別しにくいです。
「week」や「subject」等の名称をkeyにして格納することで、
どういう値を参照しているのかがわかりやすくなります。

これが100種類、200種類になるとデータ量が「無駄に」膨大になるしメリット薄い気がするんですが、実際どうなんでしょうか。

逆に、100種類、200種類のデータになった時に、単純に配列に値を入れているだけでは、
配列の何番目に何の値が入っているのかがわからなくなります。
文字列ならまだしも、数値だったら、その値が「金額」を表しているものなのか、単なる「フラグ」なのか、判断できませんよね?

そのため、オブジェクトととして、要素名を決めて値を格納することで、
コードの見通しが良くなると思っています。

ng-repeatは「全」項目をリピートしますが、実際「全」項目リピートってそんなに使うかなって思うんですが、あるとすれば例えば時限が「2」のもの曜日が「1」のもののように、膨大なデータの中から条件を決めて抽出するほうだと思います。
こういうときって普通にifなどで絞り込んでからng-repeatを用いるのですか?

実際のコードがどういうコードなのかがわからないので、何とも言えないんですが、
自分はAngularに限らず、Reactなどでも、必要な項目だけをリピートしてますよ。
データの構造などにもよりますけど。

リピートしてコードを出力するということは、レンダリングコストもかかって、処理が重くなるので、
必要に応じて、内部でデータを加工したりしてng-repeatなどを実行したりしています。

投稿2017/04/10 16:00

編集2017/04/10 16:03
chieeeeno

総合スコア217

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

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

0

配列初期化子とオブジェクト初期化子

既に指摘があるように「JSONと配列の違い」ではなく、「配列初期化子([])とオブジェクト初期化子({})の違い」ですね。

JavaScript

1// 二次元配列 2[ 3 [1,2,"有機化学","山田","3-D"], 4 [2,3,"無機化学","田中","1-B"] 5] 6 7// 配列初期化子 + オブジェクト初期化子 8[ 9 { 10 "week":1, 11 "time":2, 12 "subject":"有機化学", 13 "teacher":"山田", 14 "room":"3-D", 15 }, 16 { 17 "week":2, 18 "time":3, 19 "subject":"無機化学", 20 "teacher":"田中", 21 "room":"1-B", 22 } 23]

JSONファイルを管理する

私は配列初期化子とオブジェクト初期化子のどちらであっても問題はないと考えています。
基本的に JSONファイルは手書きで編集するものではなく、機械的に書き換える方法を用意する方が合理的だからです。
先のデータは二次元配列に出来る以上、CSVやDBで管理する事が可能であり、CSVならExcelで入力、DBならサーバサイドスクリプトで管理する為のプログラムを書けば、プログラムを理解できない人にも編集は容易でしょう。
ただし、二次元配列にする場合は1列目に列名を指定すべきだと思います。

JavaScript

1[ 2 ["week","time","subject","teacher","room"], 3 [1,2,"有機化学","山田","3-D"], 4 [2,3,"無機化学","田中","1-B"] 5]

これでこのデータをCSV/DBに取り込むことが容易となりました。
JSONフォーマットは機械的に変換しやすい形式である事が重要であり、その点を守れば、どんなフォーマットでも良いと私は考えます。

Date.prototype.getDay

・曜日(0=mon,1=tue...)

曜日は Date.prototype.getDay に準拠し、「0 = 日曜日, 1 = 月曜日, ...」にするとJavaScriptから扱いやすくなると思います。

CSV フォーマット

機械的な変換が容易であれば、JSON に拘る必要もありません。
JSON が広く使われているのは JSON パーサがネイティブで実装されており、コードに書き表すのが容易だからです。
パーサさえ用意すれば、どんなフォーマットであっても構いません。
先の二次元配列データはCSVで書き表すことも可能ですので、CSVフォーマットにする選択肢もあります。

week,time,subject,teacher,room 1,2,有機化学,山田,3-D 2,3,無機化学,田中,1-B

CSV は JSON よりもサイズ軽減できるメリットがある為、ファイルサイズを気にされるのでしたら要件に合致するかもしれません。
標準でCSVパーサは用意されていませんが、CSVは比較的シンプルな仕様なのでいくつかライブラリが出ており、場合によってはご自身で書くこともありだと思います。
参考までに、過去に私が書いたライブラリを紹介しておきます。

更新履歴

  • 2017/04/13 01:16 Date.prototype.getDay を追記
  • 2017/04/13 02:04 CSV を追記

Re: cloudspider さん

投稿2017/04/12 16:08

編集2017/04/12 17:05
think49

総合スコア18162

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

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

0

ベストアンサー

コンパイラー言語ならば

enum { ID = 0, NAME = 1, } int id = record[ID] string name = record[NAME]

などとすれば効率と可読性を両方満足させることができますが、ご存知のようにクライアントサイドでサーバーからの情報を解釈することはjavascriptにゆだねられています。この言語が意味的なチェックを実行時に行う動的型付けのインタープリタ言語である事情から、インターフェースを事前に形式的・厳密にチェックできない(それは軽快な開発ができることの代償だと思います)ため、JSONのような自己説明的なデータ形式の方が

let id = record.id
let name = record.name

のように直接系かつ明快にかけるという一点において「一定以上の品質を担保するために必要」と考えられているからではないでしょうか。もちろんjavascriptでも、

const ID = 0, NAME = 1;
let id = record[ID]
...

などと書けはするわけですが、const ID = 0がインターフェース先となるサーバー側の定義と一致しているかどうかはキーが名前でない(つまり直感的でない)ため、何か機械的な事前チェックでもない限り「間違いの元になる」と多くの開発者が感じるのではないかと思います。そもそもキーが数字で充分なのであれば構造体のメンバーを名前でアクセスできるといった一般の言語の機能は必要ないということになってしまいますね。

これが100種類、200種類になると

一つのレコードにぶら下がる属性の種類が数十以上にもなるような設計は一般的でないと思います。つまりJSONで何十もの属性を表現する場面が一般的とはいえないと思います。

一方同一の形式のものを複数扱うという場面ならjavascriptでも普通に配列を使うことでしょう。「それぞれ意味が異なる個別の属性の表現」と「内容が全て同じのものの列」を質問者さんは同列に比較しているように感じますが、自分は「それらは区別して考えるべきもの」というふうに思います。

ただ、JSONは冗長なデータ表現であることは質問者さんがおっしゃるとおりだと思います。正直自分もそう思いました。しかし前述したような話と、現在の計算機の処理能力・通信インフラの能力などのバランスを考えたとき、JSONのような冗長な形式でも充分実用になるということなのだと思います。そもそもがHTMLやXMLはバイナリーに比べると冗長きわまる形式ですが、今日それが「冗長すぎて効率がわるい!全部バイナリーにすべき」という人はあまりいないと思います。(XMLやHTMLにはその形式を厳密に定義するDTDがありJSONにはないという違いはあるでしょうから一概に同じとはいえないかも知れませんが、人間がそれを見て直感的に意味を把握しやすい可読可能なテキストになっているという点では似ていると思います。)

他にも色々と理由はあるかも知れませんが素朴な感覚からコメントしてみました。

投稿2017/04/10 16:32

KSwordOfHaste

総合スコア18394

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

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

0

10個くらいなら確かにコードも読みやすくていいと思うのですが、

これが100種類、200種類になるとデータ量が「無駄に」膨大になるしメリット薄い気がするんですが、実際どうなんでしょうか。

JSONに限った話ではありませんが、
HTMLやCSS、JSONなどのファイルはサーバとクライアント間の通信時にgzipで圧縮されます。
なので、テキストファイルの送受信は多少膨大になっても高圧縮に出来るのであまり気にする必要はありません。
画像ファイルはアイコンレベルでも60kBみたいな馬鹿でかいファイルサイズになりますからね…

通信さえ行われてしまえば後は大差ないですね。
万に届くデータ量も瞬時に解析出来るので連想配列でのやり取りが一般的となっています。

ng-repeatは「全」項目をリピートしますが、実際「全」項目リピートってそんなに使うかなって思うんですが、あるとすれば例えば時限が「2」のもの曜日が「1」のもののように、膨大なデータの中から条件を決めて抽出するほうだと思います。

こういうときって普通にifなどで絞り込んでからng-repeatを用いるのですか?

その通り、一般的には配列を返す関数を用意してあげると良いでしょう。

HTML

1<div ng-init="time=2; week=1"> 2 <table> 3 <tr ng-repeat="user in filtered_users(users, time, week)"> 4 </table> 5</div>

JavaScript

1// 大抵はスコープの中で宣言するのでこんな感じ? 2$scope.filtered_users = function(users, time, week){ 3 if (users == null) return []; // usersがundefinedの場合エラーが出るので逃げる 4 return users.filter(function(user){ 5 return (user.week === week) && (user.time === time) 6 }) 7}

投稿2017/04/12 05:35

miyabi-sun

総合スコア21158

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

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

0

JSONでも配列で書く方法はあります。

json

1[ 2 [1,2,"有機化学","山田","3-D"], 3 [2,3,"無機化学","田中","1-B"] 4]

しかしこれだとtopoさんの言うとおりでこれだとデータの関連付けが難しくなります
しかしforのループ処理ですべてのデータを場合になると少し変わってきます
ループで文字列を使いたい場合はもう一つ配列を作ってその配列の値をkeyとして取得するというすこし遠回りな方法になります

js

1var key = ["week","time","subject","teacher","room"]; 2for(var i=0;i<json.length; i++) { 3 json[key[i]] 4}

その時にあった書き方を選ぶと良いと思います

投稿2017/04/10 16:41

yuta0801

総合スコア270

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問