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

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

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

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

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

JavaScript

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

関数

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

配列

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

Q&A

解決済

2回答

2263閲覧

XMLHttpRequestで読み込んだCSVを二次元配列に格納したいです。

fungi

総合スコア2

CSV

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

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

JavaScript

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

関数

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

配列

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

0グッド

0クリップ

投稿2021/09/28 06:20

編集2021/09/29 02:07

前提・実現したいこと

XMLHttpRequestで読み込んだCSVを二次元配列に格納したいです。

発生している問題・エラーメッセージ

関数の外に定義したresultの中にCSVを配列で入れたいのですが、 関数の外でコンソールに出力すると、 [] 0:(2)["01",100] 1:(2)["02",200] ・  ・  ・ と出力されます。 最初の[]の中に何も入っていないので、 consol.log(result[1])などにしてもundifinedになります。 CSVを読み込んで同じように出力されるという質問を見つけたのですが、 関数の中でコンソール出力することで解決されていましたので、 配列の格納方法が分かりませんでした。 いろいろ試してみましたが、にっちもさっちもいかなくなりました。 javascriptを勉強をはじめたばかりです。 ご教示お願いいたします。

該当のソースコード

javascript

1let result =[] 2 3function getCSV(){ 4 const req = new XMLHttpRequest() 5 req.open("get","abc.csv",true) 6 req.send(null) 7 8 req.onload=function(){ 9 csvArray(req.responseText) 10 } 11} 12 13function csvArray(str){ 14 const temp = str.split("\r\n") 15 16 for(let i=0;i<temp.length;++i){ 17 result[i] =temp[i].split(",") 18 } 19} 20getCSV() 21 22console.log(result) //ここの出力でおかしくなります。 23

試したこと

getCSVの中にコンソールを書くと、同様の結果になり、
csvArrayの中にコンソールを書くと、(10)[Array(2),Array(2),・・・]と出力されました。

試しにCSV読み込みを無視して、tempを普通の配列にしてみたところ、
(10)[Array(2),Array(2),・・・]と出力されました。

csvArrayの中でresultを定義して、関数の外で定義したresultをresult2にして、
csvArrayの中でresult2=resultとしてみたところ、
[]
length:0
と出力されてしまいました。

##追記

昨日fetchの方が適しているとのご意見をいただき、調べながら確認したことをまとめます。
ご教示いただいた下記コードですが、

const getCSV=()=>fetch('sample.csv').then(res=>res.text()).then(csvArray);
const csvArray=str=>str.split("\r\n").map(x=>x.split(","));

(async ()=>{
const result=await getCSV();
console.log(result); ※1
})();

//↑この外でresultを参照できませんでした。

console.log(result) //Uncaught・・・

//※1では
//(5) [Array(2), Array(2), Array(2), Array(2), Array(2)]
//0: (2) ['"0001"', '11']
//1: (2) ['"0002"', '12']
//2: (2) ['"0003"', '13']
//3: (2) ['"0004"', '14']
//のように出力され、配列になっていました。

//そこで、resultを最初に定義してみましたが、

let result = []

const getCSV=()=>fetch('sample.csv').then(res=>res.text()).then(csvArray);
const csvArray=str=>str.split("\r\n").map(x=>x.split(","));

(async ()=>{
result=await getCSV();
console.log(result);
})();

console.log(result)

//以下のような出力結果になりました。
//[]
// length: 0
// [[Prototype]]: Array(0)
//(5) [Array(2), Array(2), Array(2), Array(2), Array(2)]
// 0: (2) ['"0001"', '11']
// 1: (2) ['"0002"', '12']
// 2: (2) ['"0003"', '13']
// 3: (2) ['"0004"', '14']

resultの中身が空のままになってしまいました。
resultを配列として別の関数で参照したり、result[1]などのように扱いたいので
グローバル変数としたいと思っています。
自分でも調べながらやってみたのですが、

let result = fetch("sample.csv").then(res=>res.text()).then(function convertCSVtoArray(str){
const temp = str.split("\r\n")
for(let i=0;i<temp.length;++i){
result[i] =temp[i].split(",")
}
})

console.log(result)

//↑のようにすると、以下のように出力されます。

//Promise {<pending>}
//0: (2) ['"0001"', '11']
//1: (2) ['"0002"', '12']
//2: (2) ['"0003"', '13']
//3: (2) ['"0004"', '14']

Promiseの概念がつかめていないままなのですが、
pendingとなっているということは、値は検出してるけど、
まだresultに取得できていないということでしょうか?

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

yambejp

2021/09/28 06:41

想定する動作環境(OSやブラウザ)を提示ください
fungi

2021/09/28 06:55

申し訳ありません、追記いたしました。 Windows10でChromeで動作確認しています。
yambejp

2021/09/28 07:16

win/chromeだとXMLHttpRequestではなくfetchでよさそうですね
guest

回答2

0

ベストアンサー

javascript

1const getCSV=()=>fetch('sample.csv').then(res=>res.text()).then(csvArray); 2const csvArray=str=>str.split("\r\n").map(x=>x.split(",")); 3 4(async ()=>{ 5 const result=await getCSV(); 6 console.log(result); 7})();

微調整

Lhankor_Mhyさんのご指摘をうけて

javascript

1<script type="module"> 2let result=[]; 3const getCSV=()=>fetch('sample.csv').then(res=>res.text()).then(csvArray); 4const csvArray=str=>str.split("\r\n").map(x=>x.split(",")); 5result=await getCSV(); 6console.log(result); 7</script>

投稿2021/09/28 07:37

編集2021/09/29 04:02
yambejp

総合スコア115012

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

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

fungi

2021/09/28 07:59

ご回答ありがとうございます。 fetchについて調べましたがさっぱり分かりませんでした。 asyncもawaitもよくわからないのでその辺も調べなおしてみます。
yambejp

2021/09/28 08:07

仕組みはともかく動作するかどうかだけ確認してみてください
fungi

2021/09/28 08:24

確認してみましたが、 (async ()=>{ result=await getCSV(); console.log(result); })() の外では、 [] 0:(2)["01",100] 1:(2)["02",200] ・  ・  ・ のようになりました。
yambejp

2021/09/28 08:25

想定したデータと違いますか? ちがう場合はどういったデータを希望しますか?
fungi

2021/09/29 02:11

ご教示いただいているにも関わらず日を跨いでしまい申し訳ありません。 いただいたコードの挙動について追記いたしました。 fetchで読み込んだデータを配列且つグローバル変数として扱いたいです。 例えば、別の関数の中で、result[1]とすると["0002","12"]がとらえられるといいです。
yambejp

2021/09/29 03:29 編集

ああ、なるほど・・・ おそらくなさろうとしていることは非同期の特性上不可能です グローバルな変数に非同期で得た値を与える場合 処理がおわるのを待つ処理が必要です。 そのためには特定のスコープでasync/awaitで制御する必要があります それはグローバルな処理では難しいです (そもそもグローバルに処理する意味がありません)
yambejp

2021/09/29 04:03 編集

Lhankor_Mhyさん、ご指摘ありがとうございます たしかにmoduleでなら可能ですね 追記しておきました
fungi

2021/09/29 05:08

yambejp様、Lhankor_Mhy様、ありがとうございます! しっかり読み込むことができました。 すごいです!!
guest

0

XMLHttpRequest.open()の第3引数にtrueを渡しているので、操作は非同期になります。
非同期処理のためreq.onloadにコールバック関数をセットしていますが、
そのコールバックはいつ呼ばれるかわからない状態ですよね。
つまり、まだデータがロードされていない(したがってreq.onloadにセットしたコールバック関数が実行されていない)かもしれない時点で、console.log(result) を実行していることになります。

コールバック関数の実行が完了するまで待つか、さもなくば、まずは同期処理にしてXMLHttpRequest.responseTextを参照するといいのではないでしょうか?

下記ドキュメントを参照してください。

XMLHttpRequest - Web API | MDN

あと、余談になりますが、XMLHttpRequestも使えますが非推奨になっています。

まだXMLHttpRequestを使ってるの? fetchのすすめ - Qiita

投稿2021/09/28 06:54

編集2021/09/28 07:03
itagagaki

総合スコア8402

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

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

fungi

2021/09/28 07:53

ご回答くださりありがとうございます。 調べているときにfetchも見たんですが、さっぱり理解できなかったので…。 もう一回見直してきましたが、やっぱりさっぱり分かりませんでした。 今まで使ってきた参考書では全然間に合ってないことが分かりました。 fetchの前にPromiseとthenもさっぱり分からないので、その辺から調べてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問