文字列で指定された変数を使いたい

解決


ひさし  2006-09-15 00:15:10  No: 133251

例えば
Dim str As String = "Air_temperature(doy, yr)"
と、文字列で変数名と引数名を指定した時に

Dim doy As Integer = 1
Dim yr  As Integer = 1990
Dim x   As Single
x = str

という具合に、この文字列で指定される変数を取り出す方法は無いでしょうか?
どなたかご回答頂ければ、大変助かります。
どうぞ、宜しくお願いいたします。


通ってみた  2006-09-15 05:58:04  No: 133252

ない


特攻隊長まるるう  2006-09-15 20:22:27  No: 133253

Air_temperature は『変数』では無いと思うのですが。。。
どんな処理を実現したいのでしょうか?

キーワードと、それに対応する値を複数管理したいだけ
なら『コレクション』を使ってみるとか。
 # 単純なものなら配列でも良い気がします。。。


ひさし  2006-09-15 21:24:48  No: 133254

早速有り難うございます。

説明が足りませんでした。
Air_temperature(*,*)は、別に定義されている配列変数です。

実現したい処理についてですが、データ書き出しプログラムを作成しています。
リストボックス1に書き出し可能な変数一覧が掲載されており
ユーザーは、そのアイテムを選択して「追加ボタン」を押すことによって
リストボックス2に、書き出す変数一覧を編集します。
その後に、「書き出しボタン」を押すと、リストボックス2で選択された変数が
ファイルに書き出されるというプログラムです。

リストボックスの項目が多いため、IF文やSelect Case文を使うとコードが長くなってしまい、何とか条件式を使わずにプログラムできないかと、方法を模索しております。


ヤマ@文系  2006-09-19 06:52:15  No: 133255

Dim str As String = "Air_temperature(doy, yr)"'これでは文字列にならないかな?.NETは不得手なのでどうもわからんですが

配列でもいいですが、
文字列に対応したデータを取得したいのであれば
collectionやarrayといったクラスであれば、
indexofでサーチできるとおもいます。

えっと、list1を例えばstr()の配列
として  list2をAir_temperature(doy, yr)の配列で
対応させておけば
例えばlist1で選んだitemをstr()の配列str.indexofで'str()に重複がないと仮定してます。。

list1で選んだ文字列でサーチして配列の何番目かのindexを取得して
ari_temparatureの方でindexに対応する要素を抜き出したらどうですか?

個人的にはAir_temparature(,)と2次元にするとややこしくなるというか
メソッドを使ったことがないのでよくわかりません。

Air1() air2()みたいに分けて、1対1で対応した方がわかりやすいかもしれないです。

そうすれば
str.indexof()で調べた文字列で
air1.getvalue(index)みたいなかんじで取得できるのでは?

MSDNみたかんじでは、
2次元なら二つの要素数を計算しないといけない?感じがしたので。。

もっとスマートな方法は詳しい方に譲りたいと思います。
参考にならないかもしれませんが、すいません。


ヤマ@文系  2006-09-19 07:44:29  No: 133256

.NET Framework 2.0のgenericクラスのListを使った方が
楽かと思います。
参考までに。


ひさし  2006-09-20 23:38:58  No: 133257

ご回答ありがとうございます。

つまり、次の要領にて、リストボックスから読み取った文字列を、変数名の文字列に変換すると言うことでしょうか?

     i = List.IndexOf(リストボックスより読み取った文字列)
   str = List2.GetValue(i)
   
       i 整数
     str 文字列
   List1 変数の説明文字列
   List2 変数名

実は、ハッシュを使った同様の仕組みを考えたのですが、これですと取り出されるのは、やはり変数名の入っている文字列になってしまいます。

例えば、予め、
  Air_temperature(doy, yr)"
  soil_temperature(doy, yr)"
  cloudness_temperature(doy, yr)"
  .
  .
  .
  ↓
  climate_data(doy,yr,data_id)

といった具合に、全ての変数を、もう一次元大きな配列変数にまとめてしまえば簡単なのですが、このプログラムで扱うデータ容量は膨大でして、使用メモリー量を節約する観点から、そのような方法は避けたいと希望しています。


ヤマ@文系  2006-09-21 01:05:07  No: 133258

すいません。こちらも勘違いしていました。
変数ではなく変数の名前から変数を指定して変数の中身を取り出したいということでしょうか?

system.codedom
あたりからinvokeできませんか?
メソッドだけだったかわかりませんが。
調べてみてください。


特攻隊長まるるう  2006-09-21 02:33:11  No: 133259

とりあえずそろそろ自分の開発環境くらいは明記して欲しいですが。。。

> 使用メモリー量を節約する観点から、そのような方法は避けたいと希望しています。
…ん?。結局、
> 例えば、予め、
>   Air_temperature(doy, yr)"
>  …
予め、全ての配列データをメモリ上に用意する事が決まってるなら、
メモリ量の節約ができるものなの?…まぁ、配列の次元を増やす
方法では、連続した領域が必要になるかもしれないので(確証は
得られていません)、増やさないのでいいと思いますが。。。

だから『コレクション』というキーワードを出したわけですが、調べましたか?
キーワード(Indexでもいいでしょう)を指定すれば二次元配列を返すような
コレクションを用意して、初期化時に設定しておけば良いのでは???

> system.codedom
> あたりからinvokeできませんか?
[VB.NET]なら『リフレクション』あたりをキーワードにして調べるのも
いいでしょうね。
> 変数ではなく変数の名前から変数を指定して変数の中身を取り出したいということでしょうか?
…ボク個人は、この質問がそこまで必要な状況だとは、未だに思えないですが(^^;)


ひさし  2006-09-21 22:08:39  No: 133260

ご回答有り難うございました。

> キーワード(Indexでもいいでしょう)を指定すれば二次元配列を返すような
> コレクションを用意して、初期化時に設定しておけば良いのでは???

あ、配列変数をコレクションの要素として扱うことが出来るのですね!
早速、「変数の説明」→「変数名」のHashTableを使って、解決しました。
以下はサンプルコードです。
   
   Dim data_table As New Hashtable
   
   data_table.Add("Air temperature" , tmp_air )
   data_table.Add("Soil temperature", tmp_soil)
   data_table.Add("Total cloudiness", cloud   )
   .
   .
   .
   
こうしておいて、2次元配列変数tmp_airの要素に、このtmp_airのkeyである"Air temperature"を使って、次のようにアクセスできました。
   
   Dim x As Single = _
   CType( data_table("Air temperature")(1, 1990) , Single )

この度は、大変助かりました。有り難うございます。
なお、申し遅れましたが、こちらの開発環境はVB2005 Express Editionです。


魔界の仮面弁士  2006-09-21 22:24:39  No: 133261

>   Dim x As Single = _
>   CType( data_table("Air temperature")(1, 1990) , Single )

戻り値が常に Single 2次元配列 なのであれば、HashTable ではなく、
Dictionary を使った方が楽ですよ。CType の手間が省けますので。

' 2次元配列 tmp_air があったとして
Dim tmp_air(3, 2) As Single
'      :    
tmp_air(1, 1) = 123.45

'それを、Dictionary<> に登録しておく
Dim storage As New Dictionary(Of String, Single(,))
storage.Add("Air temperature", tmp_air)

'この方法なら、取り出すときに CType は不要となります
Dim x As Single = storage("Air temperature")(1, 1)


ひさし  2006-09-22 20:18:55  No: 133262

Dictionaryというものは知りませんでした。たしかに、ハッシュを使うよりもリストが綺麗に書けますね。

msdnからの引用(http://msdn2.microsoft.com/ja-JP/library/xfhwa508.aspx):
「Dictionary ジェネリック クラスにより、キーのセットを値のセットに対応付けることができます。ディクショナリに追加される各エントリは、値とその値に関連付けられたキーで構成されます。Dictionary クラスはハッシュ テーブルとして実装されているため、キーを使用した値の取得は非常に高速で、O(1) に近くなります。」

とありましたので、こちらの方がデータ型の変換を行わないだけ高速に処理できるような気がします。

早速利用してみようと思います。
ご教示下さいまして有り難うございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加