【问题标题】:How to store information from different datatables?如何存储来自不同数据表的信息?
【发布时间】:2013-09-07 20:37:00
【问题描述】:

我有 2 个数据表(表的第一行可能看起来像):

第一个表“差异”:

Person1| 0 | -2 | 1 |8

第二张表'年龄':

Person1| 30 | 20 | 2 | 12

我需要为每个人提供的信息是 Top3 的“差异”值(按升序排列)以及相应的年龄。例如:

Table Person1:  8 | 1 | 0
                12| 2 | 30

我可以用 sql 查询来做到这一点,在 R 中我可以使用 ListObject,但我是 vb.net 的新手,所以我想知道在 vb 中获取和存储这些信息(每个人)的最佳方法是什么.net。

【问题讨论】:

    标签: .net vb.net datatable dataset


    【解决方案1】:

    如果您对匿名类型和一些 linq-fu 感到满意,请尝试以下操作:

    Dim differences = New DataTable()
    Dim age = New DataTable()
    For Each t in {differences, age}
        For Each v in {"Key", "A", "B", "C", "D"}
            t.Columns.Add(v, If(v="Key", GetType(string),GetType(integer)))
        Next
    Next
    
    differences.Rows.Add("Person1", 0, -2, 1, 8)
    age.Rows.Add("Person1", 30, 20, 2, 12)
    
    differences.Rows.Add("Person2", 4, 5, 6, 7)
    age.Rows.Add("Person2", 1, 2, 3, 4)
    
    Dim result = from d_row in differences.AsEnumerable()
                 group join a_row in age on a_row("Key") equals d_row("key") 
                 into rows = group
                 let match = rows.First()
                 select new with
                 {
                    .Key = d_row("key"),
                    .Values = d_row.ItemArray.Skip(1).Zip(match.ItemArray.Skip(1), Function(a, b) Tuple.Create(a, b)) _
                                                     .OrderByDescending(Function(t) t.Item1) _
                                                     .Take(3) _
                                                     .ToArray()
                 }
    

    结果:

    这个想法是加入数据表,将整数值压缩成对,对对进行排序,然后取出每组的前三对。

    一个更短但可能更慢的方法是省略连接并使用类似的东西

    Dim result = from d_row in differences.AsEnumerable()
                 let match = age.AsEnumerable().Single(Function(r) r("Key") = d_row("Key"))
                 select new with { ... }
    

    请注意,为简洁起见,我在示例中省略了空值检查。


    回应您的评论:

     ...
     select new with
     {
        .Key = d_row("key"),
        .Values = d_row.ItemArray.Zip(age.Columns.Cast(Of DataColumn), Function(t, c) Tuple.Create(c.ColumnName, t)) _
                                 .Skip(1) _
                                 .Zip(match.ItemArray.Skip(1), Function(a, b) Tuple.Create(a.item2, b, a.item1)) _
                                 .OrderByDescending(Function(t) t.Item1) _
                                 .Take(3) _
                                 .ToArray()
     }
    

    【讨论】:

    • 太好了,谢谢你的回答!!我只是试着理解你的代码。一个问题。 “linq-fu”是指“linq 功能”还是linqfu.codeplex.com
    • @ruedi linq-fu 在功夫意义上;也许您已经听说过 google-fu 这个词。这只是某种玩笑:-)
    • 啊好吧!! :) 我已经把我的鼻子放进了一本 linq 书。谢谢!
    • 抱歉,我还有一个问题。我怎样才能输出数组元素?我试过: 为每个 res 在结果 output.AppendLine(res.ToString) Next MsgBox(output.ToString) 中将输出调暗为新 System.Text.StringBuilder 但没有成功。我也尝试过类似的东西: MsgBox(result(0).Values.ToString) 但就是无法得到你得到的输出。
    • 你可以使用类似String.Join(Environment.NewLine, result.Select(Function(a) String.Format("{0}: {1}", a.Key, String.Join(", ", a.Values.Select(Function(t) String.Format("[{0} {1}]", t.Item1, t.Item2))))))的东西来创建一个简单的字符串输出。 result 包含一个匿名类型的集合。这种类型有两个属性:第一个是Key,它只包含键列,另一个属性是Values,它包含一个Tuple(Of Integer, Integer) 的数组。在这些元组中,Item1 是来自differences 的值,Item2 是来自age 的值。
    猜你喜欢
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 2015-02-05
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    相关资源
    最近更新 更多