【问题标题】:List(Of ClassA) contains a List(of ClassB) and in it a string. Check if the new string already existsList(Of ClassA) 包含一个 List(of ClassB) 和一个字符串。检查新字符串是否已经存在
【发布时间】:2021-11-10 02:24:25
【问题描述】:

我有一个 List(of ClassA),其中包含一个 List(of ClassB)。这包含一个名为“标题”的字符串。 我使用文本框读入了一个新字符串。我想检查新字符串是否已经存在。

我之前的代码可以工作,但我认为可以以更优雅的方式完成。我觉得有点困难,因为我有这个类结构。我为您创建了一个新项目,并且只复制了必要但可重现的源代码。

Form1.vb

Imports Microsoft.VisualBasic.ControlChars
Public NotInheritable Class FormMain
    Private allA As New List(Of ClassA)
    Private the_new_String As String = ""

    Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        allA.Add(New ClassA)
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        For i As Integer = 0 To allA.Count - 1 Step 1
            For j As Integer = 0 To allA(i).allB.Count - 1 Step 1
                If allA(i).allB(j).Heading = the_new_String Then
                    MessageBox.Show($"Diesen Titel gibt es bereits.{NewLine}This title already exists.",
                                    "",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information)
                    Return
                End If
            Next
        Next
    End Sub

    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        the_new_String = TextBox1.Text
    End Sub
End Class

ClassA.vb

Public Class ClassA
    Public allB As New List(Of ClassB)

    Public Sub New()
        allB.Add(New ClassB())
    End Sub
End Class

ClassB.vb

Public Class ClassB
    Public Heading As String = "Test"
End Class

【问题讨论】:

    标签: vb.net contains


    【解决方案1】:

    您拥有的嵌套循环没有任何问题。您所做的任何其他事情最终都会编译为相同的嵌套循环(尽管循环语句可能会隐藏在 Linq 函数调用中)。例如,在发布的另一个答案中,每个Any 调用都隐藏了一个循环。

    作为另一种选择,您可以考虑使用SelectMany,这是用于扁平化层次结构的 Linq 例程。

    结果是,

    If allA.SelectMany(Function(a) a.allB.Select(Function(b) b.Heading)) _
           .Any(Function(heading) heading = testString) Then
        'Proposed heading already exists
    End If
    

    我相信这最终会产生与您的原始代码或其他答案中的代码相似的算法效率。 SelectManySelectAny 都应该使用延迟执行,所以我认为一旦找到匹配项而无需额外迭代,它就会跳出隐式嵌套循环。 (很容易推断 Linq 将为您提供的集合操作,但识别隐藏在语句后面的循环复杂性并不一定容易,尤其是当某些 Linq 函数会急切地求值而其他函数会延迟时。)

    【讨论】:

    • 这很有趣。我认为任何命令都会更有效。假设这些现成的命令是高度优化的。 ? 很高兴知道。谢谢,克雷格。
    • @Daniel 你说得对,它们是高度优化的。我重新考虑了效率并相应地编辑了我的答案。我认为你只会得到一个统一的序列,它会一直运行到匹配然后退出。
    【解决方案2】:
    If allA.Any(Function(a) a.allB.Any(Function(b) b.Heading = the_new_String)) Then
        'The specified text already exists.
    End If
    

    【讨论】:

    • 那很快。谢谢你。因此,您使用Any 并在此函数中再次使用Any
    猜你喜欢
    • 2013-03-14
    • 1970-01-01
    • 2013-03-13
    • 2017-08-29
    • 1970-01-01
    • 2014-04-14
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多