C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ハッシュテーブルに関する変数

[トピック内 15 記事 (1 - 15 表示)]  << 0 >>

■103091 / inTopicNo.1)  ハッシュテーブルに関する変数
  
□投稿者/ どんき (1回)-(2024/05/09(Thu) 11:49:23)

分類:[.NET 全般] 



VB.NETに関する質問です。


1 男 日本人 180cm台 70kg台 
2 女 中国人 170cm台 60kg台 
3 女 韓国人 180cm台 50kg台 
・・・・


みたいなデータがあったとして、
中国人 170cm台
に該当する全データのインデックスを抽出するようなことを行いたいのですが、
こういったクラス・変数はございますでしょうか?

disctiotionaryを使うことを考えたのですが、
これはキーと値のペアしか保存できないようです。
普通にforループで検索するしかないでしょうか?




引用返信 編集キー/
■103092 / inTopicNo.2)  Re[1]: ハッシュテーブルに関する変数
□投稿者/ WebSurfer (2897回)-(2024/05/09(Thu) 12:57:47)
No103091 (どんき さん) に返信

データを保持する class を定義し、List<T> 作って linq で抽出してはいかがですか?
引用返信 編集キー/
■103093 / inTopicNo.3)  Re[1]: ハッシュテーブルに関する変数
□投稿者/ kiku (425回)-(2024/05/09(Thu) 14:13:33)
2024/05/09(Thu) 14:21:19 編集(投稿者)

No103091 (どんき さん) に返信

いくつか思いつきました。
1.メモリ上、List<T>でLINQ検索
  一番手軽。件数が少なければ、結局これが一番速そう。
2.SQLiteでメモリ上で動作させる。selectで検索
  1と比べて速度差がどの程度出るかは、自身で検証して、メリットありそうなら採用で良さそう。
3.SQLiteでファイル上で動作させる。selectで検索
  1と比べて速度差がどの程度出るかは、自身で検証して、メリットありそうなら採用で良さそう。
4.sqlserverやoracleなどのDBを利用する。selectで検索
  件数が多いならやっぱりDBの利用を考えた方が良いです。

対象のデータは、最終的に保存する必要があるのかどうかでも
判断が変わってくると思います。
保存する必要あるなら、DBかファイルになると思うので、
DBなら、sqlserver、oracleなどのDBへ。
ファイルなら、シリアライズしてxmlなりjsonなどで出力もありだし、
SQLliteなら、内部はファイル管理なので、そのまま利用できますね。

どんな機能を作りたいかによって自身で選択することになると思います。

引用返信 編集キー/
■103094 / inTopicNo.4)  Re[1]: ハッシュテーブルに関する変数
□投稿者/ 魔界の仮面弁士 (3769回)-(2024/05/09(Thu) 14:22:03)
2024/05/09(Thu) 14:26:13 編集(投稿者)

No103091 (どんき さん) に返信
> disctiotionaryを使うことを考えたのですが、
> これはキーと値のペアしか保存できないようです。
Dictionary にしたいということならば、
一つのキーに 複数の情報を まとめればよいのでは無いでしょうか。

「中国人 170cm台」というのが、
and 条件なのか or 条件なのかによりますが、and 条件なら
"中国人/170cm台" のように、連結した文字列をキーにしてもよいでしょう。
あるいは、タプルをキーにすることもできるかと。


あるいは、 dict("中国人")("170cm台") のように、
Dictionary コレクションの要素に、別の Dictionary を階層的に持たせるとか。
 Dictionary(Of String, Dictionary(Of String, Lisft(Of Integer)))
 Dictionary(Of String, Dictionary(Of String, Integer()))


> 普通にforループで検索するしかないでしょうか?
元データの持ち方次第ですが、自分ならとりあえず Linq を使うと思います。
引用返信 編集キー/
■103095 / inTopicNo.5)  Re[1]: ハッシュテーブルに関する変数
□投稿者/ bun (4回)-(2024/05/09(Thu) 14:40:23)
2024/05/10(Fri) 13:15:25 編集(投稿者)

C#になっちゃいますが...

class Person
{
  public int index; // インデックス
  public int sex; // 性別(男:1, 女:2)
  public int country; // 国番号
  public int tall; // 身長
  public int weight; // 体重
}
だとして、List<Person> personList; の形でデータを持っているとします。

 var personDic = personList.ToLookup(x => new { x.country, x.tall });
とすれば、国番号、身長の双方をキーとする1:多のハッシュ辞書が作成できます。

あとは、
 int country = 86; // 中国
 int tall = 170; // 170cm
 var persons = personDic[new { country, tall }];
とすれば、該当する人をハッシュ検索できます。

ここまで来ちゃえば、インデックス抽出にこだわらないでしょうが...
インデックス抽出するなら以下です。
 var persons_idx = persons.Select(x => x.index);
引用返信 編集キー/
■103096 / inTopicNo.6)  Re[1]: ハッシュテーブルに関する変数
□投稿者/ kiku (426回)-(2024/05/09(Thu) 14:53:40)
No103091 (どんき さん) に返信
辞書を多重に持つ方法など、実装によって速度検証しているサイトを見つけました。
こちらも参考になるかも。
https://docs.sakai-sc.co.jp/article/programing/csharp-performance.html
引用返信 編集キー/
■103098 / inTopicNo.7)  Re[1]: ハッシュテーブルに関する変数
□投稿者/ WebSurfer (2898回)-(2024/05/09(Thu) 15:52:29)
No103091 (どんき さん) に返信

No103092 の私の回答、

> データを保持する class を定義し、List<T> 作って linq で抽出してはいかがですか?

は言葉だけでは質問者さんに分からないかもしれないので、サンプリコードを載せて
おきます。これはやりたいこととは違うということならどこがどう違うか書いてくだ
さい。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp8
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var list = new List<PersonalData>
            {
                new PersonalData {Index = 1, Sex= "男", Nationality = "日本人", Hieght = 180, Weight = 70 },
                new PersonalData {Index = 2, Sex= "女", Nationality = "中国人", Hieght = 170, Weight = 60 },
                new PersonalData {Index = 3, Sex= "女", Nationality = "韓国人", Hieght = 180, Weight = 50 },
            };

            var result = list.Where(p => p.Nationality == "中国人" && p.Hieght == 170);

            foreach (var p in result)
            {
                Console.WriteLine($"{p.Index}, {p.Sex}, {p.Nationality}, {p.Hieght}, {p.Weight}");
            }

            // 結果:
            // 2, 女, 中国人, 170, 60
        }
    }

    public class PersonalData
    {
        public int Index { get; set; }
        public string Sex { get; set; }
        public string Nationality { get; set; }
        public int Hieght { get; set; }
        public int Weight { get; set; }
    }
}

引用返信 編集キー/
■103099 / inTopicNo.8)  Re[1]: ハッシュテーブルに関する変数
□投稿者/ 魔界の仮面弁士 (3770回)-(2024/05/09(Thu) 16:34:27)
No103091 (どんき さん) に返信
> VB.NETに関する質問です。

何故か C# なサンプルばかりになってしまっているので、一応 VB 版も。



Module Module1
  Class Sample
    Public Gender As String
    Public Category As String
    Public Height As Integer
    Public Weight As Integer
    Public Sub New(g$, c$, h%, w%)
      Gender = g
      Category = c
      Height = h
      Weight = w
    End Sub
  End Class

  Private Samples As New List(Of Sample)() From {
    New Sample("男", "日本人", 180, 70),
    New Sample("女", "中国人", 170, 60),
    New Sample("女", "韓国人", 180, 50)
  }

  Sub Main()
    'インデックス化
    Dim indexed = Samples.Select(Function(p, i) (i, p)).ToArray()

    '「中国人 170cm台」を満たす全データのインデックス
    Dim and条件の場合 As Integer() = indexed.Where(Function(x) x.p.Category = "中国人" AndAlso x.p.Height = 170).Select(Function(x) x.i).ToArray()
    'Dim or条件の場合 As Integer() = indexed.Where(Function(x) x.p.Category = "中国人" OrElse x.p.Height = 170).Select(Function(x) x.i).ToArray()

    '取得したインデックスの確認
    Array.ForEach(and条件の場合, AddressOf Console.WriteLine)

    Console.ReadKey()
  End Sub

End Module
引用返信 編集キー/
■103100 / inTopicNo.9)  Re[1]: ハッシュテーブルに関する変数
□投稿者/ 魔界の仮面弁士 (3771回)-(2024/05/09(Thu) 17:01:41)
No103091 (どんき さん) に返信
> ハッシュテーブルに関する変数

これは、System.Collections.Hashtable クラスのことでしょうか?
https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.hashtable?view=netframework-4.8

Hashtable は、.NET Framework 1.x 時代に使われていた古いクラス設計であり、
新規案件での利用は推奨されていません。
 ・コンパイル時に型チェックされないので、間違った型を格納しても実行時まで検出できない
 ・値型を保持する場合、Object 型にボックス化されるため、パフォーマンスが悪い
 ・中身を操作する際に、ボックス化解除やレイトバインディングが必要になってしまう

現在はジェネリックなコレクションが使えるので、
Hashtable の代わりに、Dictionary(Of TKey, TValue) を用いるべきです。
https://learn.microsoft.com/ja-jp/dotnet/standard/collections/when-to-use-generic-collections
※あるいは ConcurrentDictionary(Of TKey, TValue)
引用返信 編集キー/
■103103 / inTopicNo.10)  Re[2]: ハッシュテーブルに関する変数
□投稿者/ どんき (2回)-(2024/05/11(Sat) 22:05:08)
皆さんありがとうございます。

使い方は分かりました。


ただ、普通に配列を宣言しておいて、
自分でwhereやselectに相当するサブルーチンを作っておけば、
LinqやListを使うメリットはあまりないように思ったのですが
いかがでしょうか?


引用返信 編集キー/
■103104 / inTopicNo.11)  Re[3]: ハッシュテーブルに関する変数
□投稿者/ とっちゃん (823回)-(2024/05/11(Sat) 22:28:45)
No103103 (どんき さん) に返信

> ただ、普通に配列を宣言しておいて、
> 自分でwhereやselectに相当するサブルーチンを作っておけば、
> LinqやListを使うメリットはあまりないように思ったのですが
> いかがでしょうか?
>
Linq は List だけではなく、配列や Dictionary など IEnumerable(Of T)インターフェースを持つものが相手なら
どのようなコレクションクラスであっても利用できます。

なので、データをどういう形で持つのかにかかわりなく Linq は利用できると思います。

自作するよりは実行速度的にも速いと思います(ただし遅延評価なのでわかりにくい)。

引用返信 編集キー/
■103105 / inTopicNo.12)  Re[3]: ハッシュテーブルに関する変数
□投稿者/ WebSurfer (2899回)-(2024/05/12(Sun) 09:45:36)
No103103 (どんき さん) に返信

> ただ、普通に配列を宣言しておいて、
> 自分でwhereやselectに相当するサブルーチンを作っておけば、

そういうのは今どきはやらないです。時代に取り残されないように、新しい(linq は
新しくはないですが)技術を取り入れるべきだと思います。

趣味でやってるから今のままで困らないということでも、こういう場所で質問などをす
る場合、話にについていけてないのでは?

> LinqやListを使うメリットはあまりないように思ったのですが
> いかがでしょうか?

それは質問者さんがその世界に入ってないからそう思うだけでしょう。例えば以下のよ
うなアプリで List, Linq を使わないで、配列+whereやselectに相当するサブルーチン
だけ使ってやるのは、自分的には想像を絶する話です。

ASP.NET MVC でページング (CORE)
http://surferonwww.info/BlogEngine/post/2021/01/30/paging-in-aspnet-core-mvc-application.aspx



引用返信 編集キー/
■103106 / inTopicNo.13)  Re[1]: ハッシュテーブルに関する変数
□投稿者/ furu (227回)-(2024/05/12(Sun) 10:41:49)
No103091 (どんき さん) に返信
> disctiotionaryを使うことを考えたのですが、
> これはキーと値のペアしか保存できないようです。
キーと値のペアしか保存できないですけど
disctiotionaryでも可能です。

キーはタプルを使うと複数の項目に対応できます。
値はリストで対応できます。

Private Dict As New Dictionary(Of (国 As String, 身長 As Int32), List(Of Integer)) From {
    {("日本人", 180), New List(Of Integer)(New Integer() {1, 6})},
    {("中国人", 170), New List(Of Integer)(New Integer() {2, 4, 5, 7})},
    {("韓国人", 180), New List(Of Integer)(New Integer() {3})}
}

Dim インデックスList = Dict(("中国人", 170))

引用返信 編集キー/
■103113 / inTopicNo.14)  Re[2]: ハッシュテーブルに関する変数
□投稿者/ とっちゃん (827回)-(2024/05/13(Mon) 01:39:44)
No103106 (furu さん) に返信
> ■No103091 (どんき さん) に返信
>>disctiotionaryを使うことを考えたのですが、
>>これはキーと値のペアしか保存できないようです。
> キーと値のペアしか保存できないですけど
> disctiotionaryでも可能です。
>
> キーはタプルを使うと複数の項目に対応できます。
> 値はリストで対応できます。
>
> Private Dict As New Dictionary(Of (国 As String, 身長 As Int32), List(Of Integer)) From {
> {("日本人", 180), New List(Of Integer)(New Integer() {1, 6})},
> {("中国人", 170), New List(Of Integer)(New Integer() {2, 4, 5, 7})},
> {("韓国人", 180), New List(Of Integer)(New Integer() {3})}
> }
>
> Dim インデックスList = Dict(("中国人", 170))

ここにぶら下げるのはどうなの?とは思いますが、
Dictionary のキーは、ユニークである必要があるので
tupleにすれば解決するとは限りません。

データに一意性が必ずあるというものなら(例えば通番のようなものがあるなど)まだしも
そうではないのなら Dictionary のようなコレクションクラスの利用は
難しいともいます。

プログラム埋め込みかつリードオンリーじゃない限りは
List(Of T)でよいと思います。.NET の List はその名前と異なり可変長配列なので。
ほかの言語(JavaやC++等々)でいう List に当たるのは LinkedList(Of T)になります。

引用返信 編集キー/
■103115 / inTopicNo.15)  Re[3]: ハッシュテーブルに関する変数
□投稿者/ furu (228回)-(2024/05/13(Mon) 11:58:57)
No103113 (とっちゃん さん) に返信
キーをタプルにすることで
disctiotionaryでも可能であることを書きました。
魔界の仮面弁士さんも
> あるいは、タプルをキーにすることもできるかと。
と書かれています。

> ここにぶら下げるのはどうなの?とは思いますが、
> Dictionary のキーは、ユニークである必要があるので
> tupleにすれば解決するとは限りません。
>
> データに一意性が必ずあるというものなら(例えば通番のようなものがあるなど)まだしも
> そうではないのなら Dictionary のようなコレクションクラスの利用は
> 難しいともいます。
国,身長のペアでキーをユニーク(一意)にします。
値はインデックスのListです。

全データのインデックスを抽出したとのことでしたので
国,身長からインデックスのListを取得できる
disctiotionaryを書いてみました。

性別や体重を含めた元データはList(Of T)でいいと思います。
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ