从数据表中删除重复项[关闭]
Posted
技术标签:
【中文标题】从数据表中删除重复项[关闭]【英文标题】:Removing duplicates from datatable [closed] 【发布时间】:2014-06-08 17:10:30 【问题描述】:我正在尝试删除类似于this question 的数据表中的重复项。但是,当我这样做时,我需要在有序数据集上进行,因为标准之一是时间是我的列之一,我只需要保留最早的时间实例。
我也在ordered lists from a datatable 上遇到过这个问题,但我不确定如何将两者结合起来。
基本上,我正在将文件读入数据集中,然后我想按时间和其他三列排序,并删除所有重复项,留下最早的时间实例。有问题的列是名称 (int)、电话号码 (long)、时间 (int) 和位置 (string)。如果姓名、电话和位置重复,请在第一次(最早)时间后删除所有内容。
dsHoldingSet.Tables["FileData"].Columns.Add("location", typeof(string));
dsHoldingSet.Tables["FileData"].Columns.Add("name", typeof(int));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(string));
dsHoldingSet.Tables["FileData"].Columns.Add("time", typeof(int));
dsHoldingSet.Tables["FileData"].Columns.Add("phone", typeof(long));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(int));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(string));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(string));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(string));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(int));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(int));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(string));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(int));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(int));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(long));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(string));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(string));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(Boolean));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(string));
dsHoldingSet.Tables["FileData"].Columns.Add("field", typeof(string));
这是表定义,然后我们在验证文件中的行时添加行。
【问题讨论】:
您可以使用 LINQ 在您的DataTable
上执行 OrderBy
,您可以添加一些与您的问题相关的代码吗?
@Habib - 我没有代码。我有一个需要对其进行操作的数据集,并且我一直在阅读以了解如何执行我需要的操作。
很难回答你的问题。您可以显示您的 DataSet/DataTable 是如何定义的,列是什么(名称和类型)。你想如何获得不同的价值观?您是否希望根据单列/多列获得不同的值。您喜欢如何订购它们(基于哪一列)。这将为社区提供更好的回复选择。
【参考方案1】:
我们要做的是按不同的值对行进行分组。如果我们想对 DataTable 使用 LINQ,最简单的方法是使用内置的DataTable.AsEnumerable()
extension method。这将为您返回一个IEnumerable<DataRow>
。
一旦我们得到它,我们需要从三个值的组合中构造一个可比较的对象。这里我使用了字符串连接的方式,因为字符串比较容易比较。还有其他方法可以做到这一点,但这个很简单:
姓名|电话|位置
这会产生IGrouping<string, DataRow>
的序列。每个分组也是一个IEnumerable<DataRow>
,它代表该组的子集。因此,如果我们按时间对每个分组对象进行排序,然后取出第一个,那就是第一行。
这是完整的代码。
var rows = dsHoldingSet.Tables["FileData"].AsEnumerable()
.GroupBy(row => string.Format("0|1|2",
row.Field<string>("name"),
row.Field<string>("phone"),
row.Field<string>("location"))
.Select(group =>
group.OrderBy(row => row.Field<TimeSpan>("time")).First());
其他一些注释 - phone
应该是一个字符串,而不是很长的;除非time
代表您尚未使用的其他某种度量,否则它应该是 TimeSpan 或 DateTime。加载数据集以进行操作时,您要做的第一件事是将数据强制转换为最健壮和正确的数据类型 - 它使实际操作更加容易。完成后,如果需要,您可以取消转换。
【讨论】:
时间以午夜过后的秒数为单位,而不是传统时间。 @JohnP 那么它应该是 TimeSpan。 我会继续努力的,首先我必须弄清楚你写了什么。 :) 学习曲线有时会很陡峭。上面的代码是否反映了首先将其更改为时间跨度,还是将其视为数字? @JohnP 只需将Field<DateTime>
替换为实际值类型。以上是关于从数据表中删除重复项[关闭]的主要内容,如果未能解决你的问题,请参考以下文章