プロが教えるわが家の防犯対策術!

VisualStudioのVBです。

Dim num() As String = {"4", "2", "3", "5", "2", "9", "7", "5", "8", "5"}

と言う文字列型1次元配列があった際に、

[ "2" が 2個 ] と [ "5" が 3個 ]

と結果を出す手段としてはどのような物がありますか?
ちなみにDictionaryクラスなら出来ますので、それ以外の手段を模索中です。

よろしくお願いいたします。

質問者からの補足コメント

  • 質問は文字列型で宣言し代入してますが、実数型に置き換えて頂いても構いません。
    あくまでも手段を知りたいだけですので。

      補足日時:2022/01/28 01:27
  • つらい・・・

    回答して頂きありがとうございます。
    今の所重複削除まではいけているのですが、その先がスリムにとはいかず・・・

    Dim num() As String = {"4", "2", "3", "5", "2", "9", "7", "5", "8", "5"}
    Dim num2 = num.Distinct()
    Console.WriteLine(String.Join("_", num2)) ' 4_2_3_5_9_7_8

    num2の値を基にnumのカウントが出来ればとは思っていますが、Pythonのラムダ式みたいな感じのものが出来ないかなとは思っております。

      補足日時:2022/01/28 09:12
  • つらい・・・

    Dim num() As String = {"4", "2", "3", "5", "2", "9", "7", "5", "8", "5"}
    Dim num2 = num.Distinct().OrderBy(Function(s) s)
    Dim num3 = num2.ToList().Select(Function(x) New With {.nam = x,
    .con = (num.Where(Function(y) y = x).Count())}).Where(Function(z) z.con > 1).ToArray()

    For i As Integer = 0 To num3.Length - 1
    Console.WriteLine($"[ ""{num3(i).nam}"" が {num3(i).con}個 ]")
    Next

      補足日時:2022/01/28 13:34
  • へこむわー

    結果:
    [ "2" が 2個 ]
    [ "5" が 3個 ]

    まだ未熟ですよねぇ。

      補足日時:2022/01/28 13:35

A 回答 (6件)

Sub Main()


Dim num() As String = {"4", "2", "3", "5", "2", "9", "7", "5", "8", "5"}

Dim groupValues = num _
.GroupBy(Function(value) value) _
.Select(Function(groupValue) New With {.Num = groupValue.Key, .Count = groupValue.Count()}) _
.Where(Function(groupValue) groupValue.Count > 1)

For Each groupValue In groupValues
Console.WriteLine($"[ ""{groupValue.Num}"" が {groupValue.Count}個 ]")
Next
Console.ReadLine()
End Sub

全部把握したいなら、ラムダ式のWhere行を取り除いてください。
「配列の重複する値とその個数を取得したい」の回答画像5
    • good
    • 2
この回答へのお礼

回答して頂きありがとうございます。

SQLのSELECT句で幾度もグループ化をしていながら、今回思いつかなかった(どこに入れたら良いのか不明でもあった)点につきまして、大変参考になりました。

しかも .Key や .Count の使い方につきましては ToDictionary でやったはずなのに今回それを使える事自体勉強不足でした。
(その分遠回りしてました)

貴重な参考コード大事に保管させて頂きます。

お礼日時:2022/01/29 08:49

う〜ん、多分一番シンプルなのは#2で書いたような方式になるのかなぁ。



## LibreOffice BASICでの例

REM ***** BASIC *****

Sub Main

Dim num As Variant
num = Array("4", "2", "3", "5", "2", "9", "7", "5", "8", "5")
Dim answers(10) As Integer
For counter = LBound(num) to UBound(num)
  answers(val(num(counter))) = answers(val(num(counter))) + 1
Next
For counter = LBound(answers) to UBound(answers)
  if answers(counter) > 1 Then
    Print "[",counter,"が",answers(counter),"個]"
  End if
Next
End Sub

## ここまで

と言うのも、ラムダ式を使う、ってのは一見良さそうな手に思えるんだけど、この問題の性質としては基本的に「破壊的変更」が避けられないのね。
アキュムレータ、つまり、解を保存する「場所」を書き換えないとならないから。
ラムダ式を使って、例えばmapとかfilterなんかの高階関数を使う前提は、走査する配列なり、解を保存する「変数」とかは「不変にしないとならない」って条件があって、この質問の場合、設定されたnumは変更不可として考えていいけど、解を保存する側は絶対「データを書き換えない」とならないんじゃないかなぁ・・・・・・。
つまり、関数型プログラミング的な処理が「出来ない」って前提になると思う。
そこを無理してやると、結果、シンプルさと縁がない解になっちゃうんじゃないかしらん。
    • good
    • 2
この回答へのお礼

度々の回答をありがとうございます。

確かにシンプル性としては仰るのもごもっとも。
詳しく書いて頂けた内容は今回のテキストファイルに追加し保存させて頂きます。

今回につきましてはVBAでは出来ない方法としてどんなのがある物なのかを知ってみたく、敢えてVBとして質問しました。
どう使い分けるかはその時の状況等で決めたいと思います。

お礼日時:2022/01/29 08:45

> Pythonのラムダ式みたいな感じのもの



方法: ラムダ式を作成する :

https://docs.microsoft.com/ja-jp/dotnet/visual-b …
    • good
    • 1
この回答へのお礼

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

そうなのですよね。
回答して頂いた参考サイト等は方法として見つかるのですが、『重複しない文字』と『その文字が出てくる個数』について、どのように切り分け?結合?別管理?すべきかで模索中です。

お礼日時:2022/01/28 11:03

VBは全然知らんのだけど、単純に配列使えば済むんじゃないのかしらん。


例えばVBAに近いLibreOffice Basicだと

REM ***** BASIC *****

Sub Main

Dim num As Variant
num = Array("4", "2", "3", "5", "2", "9", "7", "5", "8", "5")
Dim answers(10) As Integer
For counter = LBound(num) to UBound(num)
 answers(val(num(counter))) = answers(val(num(counter))) + 1
Next
End Sub

多分こんなカンジになる。
    • good
    • 0
この回答へのお礼

回答して頂きありがとうございます。

今の現状は補足追加しました。
配列化は確かに必要になると思うのですが、いかにスリムに行けるか?で止まっています。

お礼日時:2022/01/28 09:16

No.1の者です。



VBでしたね。 失礼しました。

VBは詳しくないので、検索しただけですが、
配列内で並べ替え。
配列の1つ目を取得、別の配列へ入れる。
配列から、1つ目を取り出し、配列に入れる。別の配列に個数1を入れる。
配列から、2つ目を取り出し、先ほどの文字と比較。 同じなら、
別の配列に1を足す。
違うなら、配列の上限を1増やす。 2つ目の文字を入れる。
別の配列の上限を1増やす。 配列に個数1を入れる。
これを、繰り返して配列内の文字を全て処理する。


先ずは、配列内を並べ替えでしょうか?
https://dobon.net/vb/dotnet/string/stringcompare …

https://smdn.jp/programming/dotnet-samplecodes/s …

配列
https://kcfran.com/2021/03/28/net-array-1/#toc7
https://turtle-engineers.com/vb-foreach/
    • good
    • 0
この回答へのお礼

再度の回答して頂きありがとうございます。

今の現状は補足追加しました。
配列化は確かに必要になると思うのですが、いかにスリムに行けるか?で止まっています。

お礼日時:2022/01/28 09:16

こんばんは。



個人的な意見になりますが、
VBAですと、Dictionaryクラスを使うのが、普通かと思います。
シート上なら、重複の削除や、新しいExcelなら、UNIQUE関数などが
ありますね。 それでリストを作って、その後にそれぞれ幾つあるか?を
カウントするでしょうか?
あとは、自分で1からコードを作るか?でしょうか?

大した解答ではありませんが。
    • good
    • 0
この回答へのお礼

早々に回答して頂きありがとうございます。
ただ、

・Excel(VBScript)にはDictionaryクラスは存在しない。(Dictionaryオブジェクトである)
・以前も勘違いされたので冒頭にて

【VisualStudioのVBです。】

と記載をしている事ですかね。
このカテはVBA専用ではなく元々VisualBasicにVBAも含めていると思ってますが、標記に問題ありなのかなって感じます。
他のサイトでも同一カテになっている所はありますが、回答者側で判断し回答分けしているようです。

お礼日時:2022/01/28 01:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A