- PR -

KeyValuePair(Of Integer, String)のコレクションよりValueに一致する最初のKeyを取得したい

1
投稿者投稿内容
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2008-02-01 15:52
環境:VS2005

Dim List As New System.Collections.Generic.List(Of System.Collections.Generic.KeyValuePair(Of Integer, String))
List.Add(New System.Collections.Generic.KeyValuePair(Of Integer, String)(1, "りんご"))
List.Add(New System.Collections.Generic.KeyValuePair(Of Integer, String)(2, "みかん"))
List.Add(New System.Collections.Generic.KeyValuePair(Of Integer, String)(3, "すいか"))
List.Add(New System.Collections.Generic.KeyValuePair(Of Integer, String)(4, "みかん"))

上記のListよりKeyValuePairのValue値「みかん」を検索し、最初に見つかったKey値を
「ループ以外」で見つける方法がありましたらご教示ください。

よろしくおねがいいたします。
rain
ぬし
会議室デビュー日: 2006/10/19
投稿数: 549
投稿日時: 2008-02-01 16:23
参考サイト:
http://www.atmarkit.co.jp/fdotnet/csharp20/csharp20_04/csharp20_04_02.html

コード:
    Private Sub FindOrange()
        Dim List As New System.Collections.Generic.List(Of System.Collections.Generic.KeyValuePair(Of Integer, String))
        List.Add(New System.Collections.Generic.KeyValuePair(Of Integer, String)(1, "りんご"))
        List.Add(New System.Collections.Generic.KeyValuePair(Of Integer, String)(2, "みかん"))
        List.Add(New System.Collections.Generic.KeyValuePair(Of Integer, String)(3, "すいか"))
        List.Add(New System.Collections.Generic.KeyValuePair(Of Integer, String)(4, "みかん"))

        Dim Orange As System.Collections.Generic.KeyValuePair(Of Integer, String) = List.Find(AddressOf IsOrange)
    End Sub

    Private Function IsOrange(ByVal item As System.Collections.Generic.KeyValuePair(Of Integer, String)) As Boolean
        Return (item.Value = "みかん")
    End Function



なお、今初めて使ってみたので、原理について質問されても答えられません(ヲイ
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2008-02-01 20:06
rain様

試してみました。

「りんご」を検索しようと思ったら
IsApple
「すいか」を検索しようと思ったら
IsWatermelon
を定義しないとダメなんでね・・・・・・


でもこのような使い方ができることを始めて知りました。
ありがとうございました!
masa
大ベテラン
会議室デビュー日: 2004/10/28
投稿数: 161
投稿日時: 2008-02-01 20:53
addressof で比較メソッドを渡してあげればよいのでこういうやり方もあるかな。
記述ミスなどはご容赦を。

変数化したいもの(この場合なら果物の種類)をプロパティに持つクラスを定義し、
そこに比較のためのメソッドを定義します。
そしてそれを addressof で呼び出します。
種類の値を変えれば別の果物の検索もできると思います。


  dim filter as KeyPairFilter(Of Integer, String) = new KeyPairFilter(Of Integer, String)("りんご")
  Dim apple As KeyValuePair(Of Integer, String) = List.Find(AddressOf filter.IsMatch)

  filter.FilterValue = "みかん"
  Dim mikan As KeyValuePair(Of Integer, String) = List.Find(AddressOf filter.IsMatch)

  public class KeyPairFilter(Of TKey, TValue)

    public sub New(filterValue as TValue)
      m_FilterValue = filterValue
    end sub

    public property FilterValue as TValue
      get
        return m_FilterValue
      end get
      set ( p_Value as TValue )
        m_FilterValue = p_Value
      end set
    end property
    private m_FilterValue as TValue

    public function IsMatch(Of TKey, TValue)(item as KeyValuePair(Of TKey, TValue))
      if ( m_FilterValue is nothing ) then return false
      return (m_FilterValue.Equals(item.Value))
    end function

  end class


[ メッセージ編集済み 編集者: masa 編集日時 2008-02-01 20:54 ]

[ メッセージ編集済み 編集者: masa 編集日時 2008-02-01 20:56 ]
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2008-02-01 22:36
masa様
サンプルコードありがとうございます。
さっそく試してみました。
このような方法もあるのですね!
勉強になります。


れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2008-02-01 23:09
> 「ループ以外」で見つける方法がありましたらご教示ください。

どうしてループ以外なのでしょうか?

出ている例は明示的にループしてるわけではないですが、
内部的にはループです。

技術的興味だけならもちろんそれで要請は満たされますが。

もしパフォーマンス的必要性があるなら
ハッシュだとかトライとかそういったものを使わないと、
あまり意味がありません。
未記入
大ベテラン
会議室デビュー日: 2006/05/19
投稿数: 125
投稿日時: 2008-02-02 09:13
れい様

実開発では
List(Of KeyValuePair(Of Integer, String))を継承したMyListクラスを作成し
Keyで検索するFindByKeyメソッド、Value値で検索するFindByValueメソッドを提供しました。メソッドではForEachで検索しています。

ただ「ループ以外」で「簡単」に検索する方法があれば、MyListクラスを作成しなくてもいいので、何か方法がないかと考えました。

教えていただいた方法でも検索できますが、
MyListクラスを使用する他開発者の方にわかりにくのでは?という点と、
MyListクラスを作る工数もKeyPairFilterクラスを作る工数もさほど変わらない
ということで、結果的に技術的興味になってしまいました。
1

スキルアップ/キャリアアップ(JOB@IT)