Visual Basic 中学校 掲示板
投稿内容
タグのない投稿を抽出
統計
RSS
Visual Basic 中学校
>
投稿一覧
>
二次元配列の要素をカウントしたいです。
タグの編集...
投稿者
緑
 (学生)   投稿日時
2022/5/12 11:12:08
フォーム上にテキストボックスを表の様に配置しており、以下の様に二次元配列を初期化するメソッドを作成しました。
Table(0,0) = TextBox1_1
Table(0,1) = TextBox2_1
~
質問といたしましては、全てのテキストボックスに何も入力されていない場合、この二次元配列はすべて空欄となると思うのですが、それを確認する方法を知りたいです。
1次元の配列なら、
変数名.Integer = 配列名.Count(Function(s)s.Length <> 0)
のようにして、0となればすべて空欄と判断していたのですが、同じように使えず悩んでいます。
ご回答よろしくお願いいたします。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/12 11:47:02
> Table(0,0) = TextBox1_1
= CInt(TextBox1_1.Text) や
= TextBox1_1.Text ではなく、
= TextBox1_1 なのですね?
つまり、TextBox 型(あるいは Control 型)の二次元配列である、と。
> それを確認する方法を知りたいです。
単純に、For Each で十分なのでは?
汎用化したいなら、拡張メソッド化すれば OK かと。
Dim
hasData =
False
For
Each
x
In
table
If
xが空ではない
Then
hasData =
True
Exit
For
End
If
Next
MsgBox(
If
(hasData,
"データ有り"
,
"全部空っぽ"
))
> 1次元の配列なら、
一次元配列なのであれば、使うべきは .All または .Any ですね。.Count ではなく。
投稿者
緑
 (社会人)   投稿日時
2022/5/12 11:55:12
ご回答ありがとうございました。申し訳ございません。
=TextBox1_1.Text
として初期化しております。以後気を付けて質問したいと思います。
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/12 12:07:00
だとすると、先の For Each の「If xが空ではない Then」のところを
If Not String.IsNullOrEmpty(x) Then
If Not String.IsNullOrWhiteSpace(x) Then
If x IsNot Nothing Then
If x <> "" Then
などのいずれかにすればよいでしょう。
どれを使うべきかはケースバイケース。
・一度も TextBox1.Text をセットしていない要素は Nothing になります。
・しかし TextBox1.Text は、空であっても Nothing は返しません。"" を返します。
・空白(WhiteSpace)文字だけが入った TextBox を空として扱うかどうか?
> 使うべきは .All または .Any ですね。.Count ではなく。
「すべて空欄かどうか」
「すべて入力済みかどうか」
「空欄がひとつでもあるか」
「入力済みがひとつでもあるか」
を調べたい場合は、All や Any の出番です。
All は「条件に一致しない要素があれば検査を打ち切って False を返す」
Any は「条件に一致した要素があれば検査を打ち切って True を返す」
という仕様です。しかし Count の場合は、常に全件が検査されることになります。
投稿者
緑
 (学生)   投稿日時
2022/5/12 13:27:25
ご回答ありがとうございました。解決いたしました。
1つでも要素が入力されているかを確認したかったため、提案していただいた4つ目のもので作業を進めてみたいと思います。
1つ疑問に思い、初心者の疑問だったら申し訳ないのですが、何故1次元の配列なら、All,Anyを利用でき、多次元ならそうではないのでしょうか?
投稿者
魔界の仮面弁士
 (社会人)   投稿日時
2022/5/12 14:05:29
> 何故1次元の配列なら、All,Anyを利用でき、多次元ならそうではないのでしょうか?
All や Any は使えませんが、Cast や OfType は使えますよね?
「If foo.All(ラムダ式) Then」という拡張メソッドは、
「If Enumerable.All(foo, ラムダ式) Then」というメソッド呼び出しとして処理されますが、
このメソッドの第一引数は、IEnumerable(Of ) を実装した型でなければいけないわけです。
https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.all?
一方 Cast や OfType の場合は、IEnumerable(Of ) ではなく IEnumerable を要求します。
https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.oftype?
二次元配列は IEnumerable ですが、 IEnumerable(Of T) では無いのです。
Dim
oneDim
As
String
() = {}
Dim
twoDim
As
String
(,) = {}
Dim
a1
As
Array = oneDim
Dim
a2
As
Array = twoDim
Dim
b1
As
IList = oneDim
Dim
b2
As
IList = twoDim
Dim
c1
As
IList(
Of
String
) = oneDim
'Dim c2 As IList(Of String) = twoDim '🚫NG
Dim
d1
As
IEnumerable = oneDim
Dim
d2
As
IEnumerable = twoDim
Dim
e1
As
IEnumerable(
Of
String
) = oneDim
'Dim e2 As IEnumerable(Of String) = twoDim '🚫NG
逆に言えば多次元配列であったとしても、OfType(Of ) なり Cast(Of ) なりを介して
IEnumerable(Of T) に揃えてしまえば、All や Any を使えることになります。
If
Not
Table.OfType(
Of
String
)().All(
AddressOf
String
.IsNullOrEmpty)
Then
MsgBox(
"入力されています"
)
End
If
あるいは、二次元配列用の Any 拡張メソッドを自作しておけば、
一次元配列同様に All や Any を使えます。
Public
Module
Module1
<System.Runtime.CompilerServices.Extension>
Public
Function
All(
Of
T)(
ByVal
source
As
T(,), predicate
As
Func(
Of
T,
Boolean
))
As
Boolean
For
Each
o
In
source
If
predicate(o)
Then
Return
False
End
If
Next
Return
True
End
Function
End
Module
投稿者
緑
 (学生)   投稿日時
2022/5/12 15:03:27
ご回答ありがとうございました。
型の大切さが身に染みてわかりました。
拡張メソッドは使ったことがなかったので使ってみたいと思います、また質問することがあると思いますがよろしくお願いいたします。