如何根据非唯一值对列表中的对象进行排序?

发布于 2024-12-21 20:56:43 字数 1895 浏览 0 评论 0原文

我正在尝试按存储的关键字对文章进行分类。我有一个类别的关键字列表,并且我希望为一篇文章分配一个关键字数最多的类别。

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

I'm trying to categorize articles by stored keywords. I have a list of keywords for a category, and I want an article to get assigned a category that has the most keyword count.

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

And this is done for each category, ran for each article. I'm trying to sort the list in order to tell which category is the best one for this article. However it is possible more than one category is the best, and that none of the categories fit. So running this did not help me:

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

Maybe I'm doing this all wrong, but so far I think I'm on the right path. (I also have a default compare in the Category class, it just wasn't working either.)

I get an exception on the sorting most likely caused because they are not unique.

The exception I get is an InvalidOperationException: Failed to compare two elements in the array. That's with using the comparer I built in the 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柠檬色的秋千 2024-12-28 20:56:43

您需要实现 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

You need to implement IComparable instead of IComparer.

IComparer would be implemented by the class performing the sorting (such as a List class) while IComparable would be implemented by the class being sorted.

For example:

Public Function CompareTo(other As ArticleCategory) As Integer Implements System.IComparable(Of ArticleCategory).CompareTo
    Return Me.tempCount.CompareTo(other.tempCount)
End Function
愛上了 2024-12-28 20:56:43

我发现的最佳解决方案是使用 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 查看

The best solution I found was using the Microsoft LINQ (a query language for objects) it works very well and quickly produces the right result.

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

Completing my solution:

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

So this is my preferred method to do a sort or a query on a list object or an array. It produces the best result, in the fastest time without having to add the IComparer implementations to your class.

Check it out at Microsoft.com

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文