获取数字范围的重复项

问题描述 投票:0回答:3

我有一个DataTable,它包含大约2500行,其中数据如下所示:

+------------+---------+---------+---------+---------+
|    Date    | Number1 | Number2 | Number3 | Number4 |
+------------+---------+---------+---------+---------+
| 12/30/2017 |    1    |    11   |   19    |    72   |
| 12/29/2017 |    4    |    7    |   21    |    48   |
|    etc.    |   etc.  |   etc.  |   etc.  |   etc.  |
+------------+---------+---------+---------+---------+

我想要做的是获得不止一次出现的数字范围。有几点需要注意,最小数字是1,最大数字是100,数字是根据它的范围升序排序的,这意味着像我的样本数据的第1行一样,它是1,11,19,72和第2行它是4,7,21,48。

我确信通过For / Next循环简单地进行多次传递可能是微不足道的,但我真的想通过LINQ查询甚至通过DataTable.Select方法更简洁。

为了澄清,我使用的是Visual Basic .NET,数据来自CSV文件。虽然如果你提供一个C#例子,我可以很容易地翻译它。

vb.net linq filtering
3个回答
0
投票

这是使用Tuple类的固定数字长度的示例。 https://dotnetfiddle.net/mfgpZO

Dim numbers as Integer = 3
        Dim dt as new Data.DataTable
        dt.Columns.Add("Date", GetType(DateTime))
        For i as Integer = 1 to numbers
        dt.Columns.Add("Number" & i, GetType(integer))
        Next

    dt.rows.Add(new Object(){"12/29/2016", "1", "2", "3"})
    dt.rows.Add(new Object(){"12/30/2016", "4", "2", "3"})
    dt.rows.Add(new Object(){"12/31/2016", "1", "2", "3"})

    Dim d as new System.Collections.Generic.Dictionary(Of Tuple(Of Integer, Integer, Integer), String)
    For Each row as Data.DataRow in dt.Rows


    Dim t as new Tuple(Of Integer, Integer, Integer)(row("Number1"), row("Number2"), row("Number3"))

If d.ContainsKey(t) Then
        Console.WriteLine("Duplicate Set Of Numbers " & d(t) & " " & row("Date").ToString())
    Else
        d.Add(t, row("Date").ToString())
        Console.WriteLine("Not a Duplicate")
    End If



    Next

0
投票

这是C#代码。

使用LINQ的美妙之处在于,一旦有了解决方案,就可以应用AsParallel()并在Parallel中运行解决方案。

1.将每一行映射为整数。

以下标识符功能就是这样。

int identifier(DataRow dr)
{
    return row.Field<int>(0) + 
           row.Field<int>(1) * 100 +
           row.Field<int>(2) * 10000 +
           row.Field<int>(3) * 1000000;
} 

2.然后按标识符对行进行分组,并对具有多个条目的过滤器组进行分组。

这将提供所有重复的事件。

dt.Select(row => new { Row = row, id = identifier(row)})
  .GroupBy(r => r.id)
  .Where(g => g.Count() > 1)
  .Select(g => g.First());

0
投票

这是一个Linq-esque“Duplicated”函数的例子。这是一个私有实现,进行错误处理的公共扩展方法留给读者练习。该函数旨在推迟执行,行进足够远,以便在每次迭代时找到下一个副本。

Private Iterator Function Duplicates(Of TSource)(ByVal source as IEnumerable(Of TSource), ByVal comparer As IEqualityComparer(Of TSource)) As IEnumerable(Of TSource)

    Dim seenElements As New HashSet(Of TSource)(comparer)
    Dim returnedElements As New HashSet(Of TSource)(comparer)

    For Each item In source
        'If adding to the set of seen elements fails, then this element is a duplicate.
        'Then, if adding to the set of returned elements succeeds, this element has not been returned before.
        If Not seenElements.Add(item) AndAlso returnedElements.Add(item) Then Yield item
    Next
End Function
© www.soinside.com 2019 - 2024. All rights reserved.