【问题标题】:Using related data stored in a 2 dimensional array使用存储在二维数组中的相关数据
【发布时间】:2016-03-13 20:12:06
【问题描述】:

我正在努力理解数组并围绕该主题进行阅读,但是当您刚刚开始编程并且没有人可以要求解释时,很多文献并不容易理解。这是我的二维数组:

        'Declare 2-diensional array of Strings
    Dim cars(,) As String =
    New String(,) {{"BMW", "Coupe", "Reg:2015", "5 Door"},
           {"Ford", "Focus", "Reg:2015", "3 Door"},
           {"Land Rover", "Discovery", "Reg:2014", "5 Door"},
           {"Vauxhall", "Astra", "Reg:2014", "3 Door"},
           {"SEAT", "Ibiza", "Reg:2013", "5 Door"}}

    ' Get bounds of the array.
    Dim bound0 As Integer = cars.GetUpperBound(0)
    Dim bound1 As Integer = cars.GetUpperBound(1)

    ' Loop over all elements.
    For i As Integer = 0 To bound0
        For x As Integer = 0 To bound1
            ' Get element.
            Dim s1 As String = cars(i, x)
            Console.ForegroundColor = ConsoleColor.Green
            Console.Write(s1 & ", ")
        Next
        Console.WriteLine()
    Next
    Console.ReadKey()
    Console.WriteLine("Please enter the name of the record you wish to view")
    Dim s = Console.ReadLine()
    Dim value As String = Array.Find(cars, Function(x) (x.StartsWith(s)))
    Console.WriteLine(value)
    Console.ReadKey()

这是导致问题的行

Dim value As String = Array.Find(cars, Function(x) (x.StartsWith(s)))

Visual Studio 提示该错误是因为“无法从这些参数推断类型参数的数据类型。明确指定数据类型可能会更正此错误。” 我无法理解这个错误的含义。请有人可以解释一下,就像在和一个 10 岁的孩子说话一样,或者也许是一个可以帮助我理解这个问题的网站。谢谢

【问题讨论】:

  • 我怀疑 find 函数需要一个单维数组。换句话说,它不会搜索您在那里的数组数组。而不是只在 find 参数中使用汽车,而是传入汽车(0)。如果您刚刚开始,我建议您在了解它们的工作原理之前不要使用扩展方法。
  • 2D 数组确实代表了很多内置功能的问题(例如 Array 中的某些功能)。甚至 LINQ 也有问题。您应该仅在需要时(即,当效率/内存问题非常重要时)以及不期望以相关方式修改包含的信息时才使用数组。对于其他情况,您应该更好地使用更友好的修改集合(列表、字典等),您可以在其中不受限制地使用 LINQ 方法。还应尽可能避免依赖 2D 集合。
  • Car {Make, Model, Year, Color, Style} 这样的类将完全保留一个对象的数据。那么List(Of Car) 会比数组更容易使用。你的时间和脑细胞最好花在学习类和列表上,这使得使用和存储对象变得更加容易
  • 没有什么是 OP 想做而 VB 做不到的
  • 建议 Plutonix 是您应该关注的,而不是旧的(和不太友好的)编程方法。无论如何,请记住数组是非常有用且最有效的集合;所以你可能想在某些情况下使用它们(我确实经常使用它们)。

标签: .net vb.net list class


【解决方案1】:

关键在于数据相关的。与其将您的“汽车”分解成碎片以存储在不同的数组中,一个类将允许您创建一个Car 对象,并将各种汽车存储在一个类型化的List 中:

五分钟介绍ClassesLists

Public Class Car
    Public Property Id As Int32
    Public Property Make As String
    Public Property Model As String
    Public Property Year As Int32
    '... etc
End Class

现在您有了一个容器来保存一辆车的所有信息。这就像Car 对象的外观蓝图。类还可以包含方法(SubFunction)来管理它们存储的数据,以便与汽车、员工或订单相关的所有内容都可以由该类管理。

Dim c As New Car          ' create a new car object
c.Make = "Mazda"
c.Model = "Miata"
c.Year = 2013

或者在声明的时候初始化:

Dim c As New Car With {.Make = "Mazda", .Model = "Miata" ...}

现在,新千年版本的数组是List。它们更容易使用,因为它们会自行调整大小:

Dim Cars As New List(Of Car)

Cars 集合只能存储汽车对象,它存储的每辆汽车都将数据保存在一起。还有许多其他集合类型,例如Dictionary,您最终会想要熟悉。将马自达添加到列表中:

' c is the car object created above
Cars.Add(c)

与数组不同,您无需知道您将使用多少辆汽车,因为它们会自行调整大小。要引用一个,Cars(n) 将引用汽车对象:

' n is the index of a car in the list
Dim str = Cars(n).Make & " is " & Cars(n).Color

使用 temp Car 变量迭代列表:

For Each c As Car In Cars   
    ' c will be Cars(0), Cars(1) etc as we step thru
    Console.WriteLine("Index {0} is a BEAUTIFUL {1} {2}",
           Cars.IndexOf(c), c.Year, c.Model)
    ' e.g
    ' "Index 4 is a BEAUTIFUL 2015 Camry"
Next

找到一个或第一个:

Dim myCar = Cars.FirstOrDefault(Function (f) f.Make = "Mazda" AndAlso f.Year = 2013)

List(Of T) 可以用作某些控件的DataSource

myDGV.DataSource = Cars

DataGridView 将为Car 类中的每个Property 创建一个列,并为列表中的每个汽车对象添加一行 - 很简单!

或者:

myListBox.DataSource
myList.DisplayMember = "Make"
myList.ValueMember = "Id"

用户将在 ListBox(或您定义的任何内容)中看到 MakeSelectedValue 将是他们选择的汽车对象的 ID,SelectedItem 将是整个汽车对象。无需遍历不同的数组来查找相关数据 - 它始终在一个位置。

【讨论】:

  • 非常感谢您提供的所有建议和信息。我会认真考虑你的所有建议。这里有很多值得考虑的地方!!
  • 字符串数组可以很容易地将一个字符串放入错误的插槽中。类属性使错误更加明显:Make = "Blue"myArray(x, 6) = "Blue" 更容易发现错误。除此之外,Class 还允许使用混合类型:string、int、DateTime 等
猜你喜欢
  • 1970-01-01
  • 2013-05-07
  • 2018-02-12
  • 2016-03-18
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
  • 2016-10-14
  • 2012-06-02
相关资源
最近更新 更多