从数据表中删除重复项[关闭]

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&lt;DateTime&gt; 替换为实际值类型。

以上是关于从数据表中删除重复项[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

每 5 分钟删除重复项 [关闭]

从 C++ 中的数组中删除重复项 [关闭]

如何在不使用 JCL 中的 XSUM 的情况下从输入文件中删除重复项并将重复项写入文件? [关闭]

使用laravel从大表中删除重复项[关闭]

从 2 个数据帧中删除重复项 [重复]

从 BLOB 数据库中删除 ComboBox 中的重复项