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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

JSON

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

JavaScript

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

1回答

1507閲覧

[JavaScript] 某サイトで紹介されていたCSVをJSONに変換する関数を理解したいのですが1点不明な点がありお知恵をお貸しください

yamazaru

総合スコア0

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

JSON

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

JavaScript

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/12/22 08:40

前提・実現したいこと

JavaScriptを使い、CSVをJSONに変換したく、調べていたところ、以下のサイトでコードが紹介されていました。

紹介されていたサイト
https://shanabrian.com/web/javascript/csv-to-json.php

コードの中をしっかり理解したく読み解いていたのですが、1点分からないことがあり、
質問をさせて頂きました。

変換したいCSVと実行する内容

まず変換したいCSVは以下とします。

csv

1a, aa, aaa 2b, bb, bbb

このCSVは、変数csvStrに格納させます。

そして、このCSV(csvStr)を後述するcsvToJson()関数でJSONに変換します。
この時に、関数に指定するオプションで、CSVのカラム名を付ける事ができます。

よって、関数実行は以下のように行います。

javascript

1csvToJson(csvStr, {columnName:['ID', '内容', '備考']});

CSVをJSONに変換する関数定義

CSVをJSONに変換する関数csvToJson()のコードは以下です。

javascript

1var csvToJson = function(csvStr, userOptions) { 2    if (typeof csvStr !== 'string') return null; 3  4    var options = { header : 0, columnName : [], ignoreBlankLine : true }; 5  6    if (userOptions) { 7        if (userOptions.header) options.header = userOptions.header; 8        if (userOptions.columnName) options.columnName = userOptions.columnName; 9    } 10  11    var rows = csvStr.split('\n'); 12    var json = [], line = [], row = '', data = {}; 13    var i, len, j, len2; 14  15    for (i = 0, len = rows.length; i < len; i++) { 16        if ((i + 1) <= options.header) continue; 17        if (options.ignoreBlankLine && rows[i] === '') continue; 18  19        line = rows[i].split(','); 20  21        if (options.columnName.length > 0) { 22            data = {}; // ここでdata配列を空にしないと、同じ値が出力される。 23            for (j = 0, len2 = options.columnName.length; j < len2; j++) { 24                if (typeof line[j] !== 'undefined') { 25                    row = line[j]; 26                    row = row.replace(/^"(.+)?"$/, '$1'); 27                } else { 28                    row = null; 29                } 30  31                data[options.columnName[j]] = row; 32            } 33            json.push(data); 34        } else { 35            json.push(line); 36        } 37    } 38  39    return json; 40};

お知恵を拝借したい点

上記関数のif (options.columnName.length > 0)のブロックで、CSVのカラム名が引数で指定されている際の処理が記述されています。
このブロックにコメントをしているのですが、data = {}; // ここでdata配列を空にしないと、同じ値が出力される。の箇所で、dataを空にしないと、同じ値が出力されてしまいます。

これの理由を知りたく、質問させて頂きました。
どうにも分からずでして…。

これdata = {};があると、最終的にjsonは以下のように出力されます。

json

10: {ID: "a", 内容: "aa", 備考: "aaa"} 21: {ID: "b", 内容: "bb", 備考: "bbb"}

しかし、ないと以下のように出力されます。

json

10: {ID: "a", 内容: "aa", 備考: "aaa"} 21: {ID: "a", 内容: "aa", 備考: "aaa"} // 同じ内容が出力される

変数dataは、関数定義の冒頭で次のように既に宣言されています。

javascript

1var json = [], line = [], row = '', data = {};

そのため、あえてifブロックの中でdata = {}; // ここでdata配列を空にしないと、同じ値が出力される。を書かなくてもよいのかなと思ったのですが、そうではないらしく。

これがないとどうして同じ値が出力されてしまうのか、理解できておらず、お知恵を拝借頂けますと有難いです。

どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

簡単に言うと変数にプリミティブ型(プリミティブラッパーオブジェクト以外初期化せずに使うと同じオブジェクトを参照するからです。
オブジェクトの初期化方法

なので以下の一文の解釈は誤りで

dataを空にしないと、同じ値が出力されてしまいます。

正しくはdataを初期化しないとです

以下、初期化の確認用コード

var data = {}; data['nakami1'] = 1; data['nakami2'] = 2; const iremono = []; iremono.push(data); console.log(iremono); data['nakami1'] = 4; data['nakami2'] = 5; console.log(iremono); data = {}; data['nakami1'] = 1; data['nakami2'] = 2; console.log(iremono);

投稿2020/12/22 09:52

hentaiman

総合スコア6426

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

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

yamazaru

2020/12/22 15:19

早々にご回答頂き有難うございます。 光明が見えた気がします。。 無知で恐縮ですが、追加で質問させてください。 お聞きしたいのは以下の点です。 >変数にプリミティブ型(プリミティブラッパーオブジェクト)以外を初期化せずに使うと同じオブジェクトを参照するからです。 これは連想配列の既存のキーと値を上書きすることはできない、という事なのでしょうか? >初期化せずに使うと同じオブジェクトを参照するからです の部分をしっかり理解したく、ご教示頂けると有難いです。
hentaiman

2020/12/22 16:30

説明する代わりに回答にもコードを載せたんですが、実行してどういう処理になってるか調べてみましたか?それとリンク先と合わせて確認すればもう少し分かるかなと思って書いた内容ですが 見ていれば、参照・代入・メモリ・プリミティブ型・オブジェクト型などの概念が分かると思います。 読んだ上で分からない点があれば、まずは質問者自身の言葉で上記の単語などを踏まえてどう理解したかを述べてください。そこに明らかな誤りがあれば指摘はします。 ※多少誤りがあっても問題無さそうなら指摘しませんが
yamazaru

2020/12/23 08:42

遅くなり失礼いたしました。ありがとうございます。回答と掲載頂いたコードでもう少し勉強してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問