Как отсортировать объект в списке по неуникальному значению? - PullRequest
1 голос
/ 18 декабря 2011

Я пытаюсь классифицировать статьи по сохраненным ключевым словам. У меня есть список ключевых слов для категории, и я хочу, чтобы статье присваивалась категория с наибольшим количеством ключевых слов.

For Each keyword As String In category.Keywords
    category.tempCount += Regex.Matches(article.Item("title").InnerXml, Regex.Escape(keyword)).Count
    category.tempCount += Regex.Matches(article.Item("description").InnerXml, Regex.Escape(keyword)).Count
Next

И это делается для каждой категории, запускаемой для каждой статьи. Я пытаюсь отсортировать список, чтобы сказать, какая категория является лучшей для этой статьи. Однако возможно, что более одной категории является лучшей, и что ни одна из этих категорий не подходит. Так что запуск этого не помог мне:

Categories.Sort(
Function(article1 As ArticleCategory, article2 As ArticleCategory)
    Return article1.tempCount.CompareTo(article2.tempCount)
End Function)

Может, я все делаю неправильно, но пока думаю, что я на правильном пути. (У меня также есть сравнение по умолчанию в классе Category, оно просто не работает).

Я получаю исключение при сортировке, которая, скорее всего, вызвана тем, что они не уникальны.

Исключением, которое я получаю, является исключение InvalidOperationException: не удалось сравнить два элемента в массиве. Это с использованием компаратора, который я встроил в ArticleClass

Imports System.Xml

Class ArticleCategory
Implements IComparer(Of ArticleCategory)

Public ReadOnly key As Int32
Public ReadOnly Name As String
Public ReadOnly Keywords As List(Of String)
Public tempCount As Integer = 0

Public Sub New(ByVal category As XmlElement)
    key = System.Web.HttpUtility.UrlDecode(category.Item("ckey").InnerXml)
    Name = System.Web.HttpUtility.UrlDecode(category.Item("name").InnerXml)

    Dim tKeywords As Array = System.Web.HttpUtility.UrlDecode(category.Item("keywords").InnerXml).Split(",")
    Dim nKeywords As New List(Of String)
    For Each keyword As String In tKeywords
        If Not keyword.Trim = "" Then
            nKeywords.Add(keyword.Trim)
        End If
    Next

    Keywords = nKeywords
End Sub

'This should be removed if your using my solution.
Public Function Compare(ByVal x As ArticleCategory, ByVal y As ArticleCategory) As Integer Implements System.Collections.Generic.IComparer(Of ArticleCategory).Compare
    Return String.Compare(x.tempCount, y.tempCount)
End Function


End Class

Ответы [ 2 ]

1 голос
/ 19 декабря 2011

Лучшим решением, которое я нашел, было использование Microsoft LINQ (язык запросов для объектов), он работает очень хорошо и быстро дает правильный результат.

Dim bestCat As ArticleCategory
bestCat = (From cat In Categories
           Order By cat.tempCount Descending, cat.Name
           Select cat).First

Завершение моего решения:

For Each category As ArticleCategory In Categories
    category.tempCount = 0

    For Each keyword As String In category.Keywords
        category.tempCount += Regex.Matches(System.Web.HttpUtility.UrlDecode(article.Item("title").InnerXml), Regex.Escape(keyword)).Count
        category.tempCount += Regex.Matches(System.Web.HttpUtility.UrlDecode(article.Item("description").InnerXml), Regex.Escape(keyword)).Count
    Next

Next

Dim bestCat As ArticleCategory

Try
    bestCat = (From cat In Categories
               Order By cat.tempCount Descending, cat.Name
               Select cat).First
Catch ex As Exception
    ReportStatus(ex.Message)
End Try

Так что я предпочитаю выполнять сортировку или запрос к объекту списка или массиву.Он дает наилучший результат в кратчайшие сроки без необходимости добавления реализаций IComparer в ваш класс.

Проверьте его на Microsoft.com

1 голос
/ 18 декабря 2011

Вам нужно реализовать IComparable вместо IComparer .

IComparer будет реализован классом, выполняющим сортировку (например, класс List), а IComparable будет реализован сортируемым классом.

Например:

Public Function CompareTo(other As ArticleCategory) As Integer Implements System.IComparable(Of ArticleCategory).CompareTo
    Return Me.tempCount.CompareTo(other.tempCount)
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...