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

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

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

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

多次元配列

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

JavaScript

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

配列

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

Q&A

解決済

1回答

1640閲覧

Javascriptの多次元配列からレコードを取り出せない(lengthが0になる)

Zen_then

総合スコア34

Chrome

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

多次元配列

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

JavaScript

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

配列

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

0グッド

0クリップ

投稿2021/05/14 19:32

Javascriptで、配列からデータを取り出そうとして躓きました。

getSensorData関数:引数のURLからJSON形式のデータを取得し、ヘッダ情報と値を多次元配列にして返却する関数です。
testFunction関数:今回困っている関数です。この関数を呼び出して、グラフの描画等の処理を作ろうとしています。
現在、テスト中につき、呼び出し元のHTMLから<body onload="testFunction()">で起動しています。

JavaScript

1function getSensorData(argUrl) { 2 let i = 0; 3 let headers = []; 4 let values = []; 5 let xhr = new XMLHttpRequest(); 6 xhr.onreadystatechange = function () { 7 if (xhr.readyState == 4 && xhr.status == 200) { 8 let resJson = JSON.parse(xhr.response); 9 for (i = 0; i < resJson.length; i++) { 10 headers.push(resJson[i].REC_TIME); 11 values.push(resJson[i].VALUE); 12 } 13 } 14 } 15 xhr.open('GET', argUrl); 16 xhr.send(); 17 return [headers, values]; 18} 19 20// 水温・気温・湿度 21function testFunction() { 22 let CD_WaterTempareture = getSensorData('https://testUrl1'); 23 let CD_Tempareture = getSensorData('https://testUrl2'); 24 let CD_Humidity = getSensorData('https://testUrl3'); 25 26 let CDH_WT = CD_WaterTempareture.slice(0, 0); ←③ 27 28 console.log("---------- DATA(ALL) ----------"); 29 console.log(CD_WaterTempareture); 30 console.log(CD_Tempareture); 31 console.log(CD_Humidity); 32 33 console.log("---------- IS-ARRAY ----------"); 34 console.log(Array.isArray(CD_WaterTempareture[0])); 35 console.log(Array.isArray(CD_Tempareture[0])); 36 console.log(Array.isArray(CD_Humidity[0])); 37 38 console.log("---------- DATA(0) ----------"); 39 console.log(CD_WaterTempareture[0]); 40 console.log(CD_Tempareture[0]); 41 console.log(CD_Humidity[0]); 42 console.log(CDH_WT); ←③ 43 44 console.log("---------- DATA(1) ----------"); 45 console.log(CD_WaterTempareture[1]); 46 console.log(CD_Tempareture[1]); 47 console.log(CD_Humidity[1]); 48 49 console.log("---------- LENGTH ----------"); 50 console.log(CD_WaterTempareture[0].length); 51 console.log(CD_Tempareture[0].length); 52 console.log(CD_Humidity[0].length); 53 54} 55

コンソールの出力結果(Chrome90.0.4430.93)

ChromeConsole

1---------- DATA(ALL) ---------- 2main.js:30 (2) [Array(0), Array(0)] ←② 3main.js:31 (2) [Array(0), Array(0)] ←② 4main.js:32 (2) [Array(0), Array(0)] ←② 5main.js:34 ---------- IS-ARRAY ---------- 6main.js:35 true ←③ 7main.js:36 true ←③ 8main.js:37 true ←③ 9main.js:39 ---------- DATA(0) ---------- 10main.js:40 [] ←Chromeコンソールで展開したらきちんと値が入っている。 11main.js:41 [] ←Chromeコンソールで展開したらきちんと値が入っている。 12main.js:42 [] ←Chromeコンソールで展開したらきちんと値が入っている。 13main.js:43 [] ←Chromeコンソールで展開したら、何も入っていない。 ←③ 14main.js:45 ---------- DATA(1) ---------- 15main.js:46 [] ←Chromeコンソールで展開したらきちんと値が入っている。 16main.js:47 [] ←Chromeコンソールで展開したらきちんと値が入っている。 17main.js:48 [] ←Chromeコンソールで展開したらきちんと値が入っている。 18main.js:50 ---------- LENGTH ---------- 19main.js:51 0 ←① 20main.js:52 0 ←① 21main.js:53 0 ←①

やりたいこと・疑問

水温・気温・湿度の情報を1つのグラフにまとめて描画したく、ヘッダの情報を1つの配列にまとめようとしました
→CD_WaterTempareture[0]とCD_Tempareture[0]とCD_Humidity[0]を結合したい。

①当初、安直に、それぞれの[0]番目の配列に対して.lengthを取得し、ループを回して結合しようとしましたが、なぜか、CD_WaterTempareture、CD_Tempareture、CD_Humidityのそれぞれの[0]番目の配列の.lengthは「0」になってしまいます。

②よくよく見てみれば、[Array(0)]となっているが、Console上で開くときちんと値が入っている。

③うまいこと配列として認識されていないんじゃないかと思い、isArrayで検査してもtrueが返却されるが、別の変数に[0]だけ代入してみたり、sliceしてみても、きちんと値が格納できません。

試してみたこと

  1. 連想配列として認識されているのかと思い、keys(配列).lengthの記述も試しましたが、改善しませんでした。
  2. 「配列っぽい何か」になっているのかなと思い、Array.from(CD_WaterTempareture[0]).lengthも試しましたが改善しませんでした。

どうしてこうなるのか、様々調べてみましたが解決策が見つからず、お知恵を拝借願いたい次第です。
よろしくお願いいたします。

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

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

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

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

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

hoshi-takanori

2021/05/14 20:38

XMLHttpRequest (に限らず、HTTP アクゼス全般) は非同期で処理されますので、getSensorData から戻った時点では、まだデータは空です。
m.ts10806

2021/05/14 21:40

実際のコードにないものは入れないようにしてください。
guest

回答1

0

ベストアンサー

XMLHttpRequestは非同期処理なので返ってきてるかどうか関係なく以後の処理に移行します。待ちません。
同期か非同期かを決定するopen()の第3引数はデフォルト「true」なので、何も指定しなかったら非同期です。

順番を担保したいのなら同期処理にするか、onreadystatechange 内でそれぞれ処理をするか、など、明示的に「処理が終わってから次の処理をする」ようにしてください。

Chromeコンソールで展開したらきちんと値が入っている。

これはおそらくブレイクポイント張って確認したものと思われますが、
ブレイクポイント張るとその分タイムラグが発生するので返ってくるための時間があった、、、と言えるかもしれません。


あともう1点。

.slice(0, 0)

startが0なのはいいとしてendが0なら何も取らないのでは。

js

1a = [1,2,3]; 2console.log(a.slice(0)) //[ 1, 2, 3 ] 3console.log(a.slice(0,0)) //[] 4console.log(a.slice(0,1)) //[ 1 ] 5console.log(a.slice(0,2)) //[ 1, 2 ] 6console.log(a.slice(0,3)) //[ 1, 2, 3 ]

Array.prototype.slice()

投稿2021/05/14 21:52

m.ts10806

総合スコア80875

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

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

Zen_then

2021/05/15 03:58

ありがとうございます。 仰る通り、XMLHttpRequestの.openの第3引数を指定したらうまく動作しました。 旧 xhr.open('GET', argUrl); 新 xhr.open('GET', argUrl, false); 助かりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問