6

文字列配列のさまざまな値から性別をMまたはFに自動修正するために、この関数を作成しました。それはうまくいきますが、私のマネージャーは彼がより効率的であると彼が言った辞書を使うように私に言いました。しかし、私にはわかりません。これがどのように行われるかを理解するのを手伝ってくれる人はいますか?ありがとう。

    Public Function AutoGender(ByVal dt As DataTable) As DataTable        

    Dim Gender As String = ""
    Dim Mkeywords() As String = {"boy", "boys", "male", "man", "m", "men", "guy"}
    Dim Fkeywords() As String = {"girl", "girls", "female", "woman", "f", "women", "chick"}
    Dim row As DataRow
        For Each row In dt.Rows
            If Mkeywords.Contains(row("Gender").ToString.ToLower) Then
                Gender = "M"
                row("Gender") = Gender
            ElseIf Fkeywords.Contains(row("Gender").ToString.ToLower) Then
                Gender = "F"
                row("Gender") = Gender
            End If
        Next
    Return dt

    End Function
4

2 に答える 2

10

Dictionary(Of String, String)この同義語が既知であるかどうかを検索するためにを実装する方法の例を次に示します。

Shared GenderSynonyms As Dictionary(Of String, String) = New Dictionary(Of String, String) From
    {{"boy", "M"}, {"boys", "M"}, {"male", "M"}, {"man", "M"}, {"m", "M"}, {"men", "M"}, {"guy", "M"},
     {"girl", "F"}, {"girls", "F"}, {"female", "F"}, {"woman", "F"}, {"f", "F"}, {"women", "F"}, {"chick", "F"}}

Public Function AutoGender(ByVal dt As DataTable) As DataTable
    If dt.Columns.Contains("Gender") Then
        For Each row As DataRow In dt.Rows
            Dim oldGender = row.Field(Of String)("Gender").ToLower
            Dim newGender As String = String.Empty
            If GenderSynonyms.TryGetValue(oldGender, newGender) Then
                row.SetField("Gender", newGender)
            End If
        Next
    End If
    Return dt
End Function

コレクションを初期化するためにリテラルを使用する便利な方法であるディクショナリを埋めるためにコレクション初期化子を使用したことに注意してください。メソッドを使用することもできます。Add

編集:もっと簡潔かもしれないもう1つのアプローチは、2つを使用することですHashSet(Of String)。1つは男性の同義語用で、もう1つは女性用です。

Shared maleSynonyms As New HashSet(Of String) From
    {"boy", "boys", "male", "man", "m", "men", "guy"}
Shared femaleSynonyms As New HashSet(Of String) From
    {"girl", "girls", "female", "woman", "f", "women", "chick"}

Public Function AutoGender(ByVal dt As DataTable) As DataTable
    If dt.Columns.Contains("Gender") Then
        For Each row As DataRow In dt.Rows
            Dim oldGender = row.Field(Of String)("Gender").ToLower
            Dim newGender As String = String.Empty
            If maleSynonyms.Contains(oldGender) Then
                row.SetField("Gender", "M")
            ElseIf femaleSynonyms.Contains(oldGender) Then
                row.SetField("Gender", "F")
            End If
        Next
    End If
    Return dt
End Function

また、 AHashSetは一意である必要があるため、重複を含めることはできませんStrings(のキーのようにDictionary)が、キーと値のペアではなく、セットのみです。

于 2012-06-21T10:05:25.403 に答える
3

両方の配列を辞書に変更し、のContainsKey代わりに実行するだけですContains

Dim Mkeywords = New Dictionary(Of String, String) From
    {{"boy", ""}, {"boys", ""}, {"male", ""}, {"man", ""}, {"m", ""}, {"men", ""}, {"guy", ""}}

(そして女性のためのスーツに従ってください)

ただし、お気づきかもしれませんが、これらの空の文字列をすべて入力しました。これは、辞書にはキーだけでなく値も含まれているためですが、値を使用していないため、空の文字列にしました。同じO(1)ルックアップを持ちながら、すべての無関係な値を回避するHashSetには、同様の方法でを使用できます。

今変更する必要があるのは、私が言ったように、使用することだけですContainsKey(または、HashSetそのルートに行く場合は、それでもContains):

If Mkeywords.ContainsKey(row("Gender").ToString.ToLower) Then

最後に、データのサイズが大幅に増加し始めた場合にのみ、これは「より効率的」になります。今のところ、これらのいくつかの要素だけで、辞書を使用するのはさらに遅くなる可能性があります。

于 2012-06-21T10:02:30.367 に答える