使用LINQ从不同组中选择重复值

时间:2016-03-05 04:38:36

标签: c# linq datatable

我有一个Datatable,如下所示,我想从其他类中选择重复的名称

Name    Class
Akbar   1B
Akbar   1B
Amar    1A
Amar    1C
Antoney 1A
Bindhu  1B
Bindhu  1D
John    1C
Raj     1B
Bindhu  2A

结果应如下

Amar    1A
Amar    1C
Bindhu  1D
Bindhu  1B
Bindhu  2A

提前感谢任何指导

代码

var dtStudents = new DataTable();
dtStudents.Columns.Add("StudentID", typeof(int));
dtStudents.Columns.Add("StudentName", typeof(string));
dtStudents.Columns.Add("Class", typeof(string));
dtStudents.Columns.Add("ContactNo", typeof(string));

DataRow drStudent = dtStudents.NewRow();

drStudent["StudentID"] = 1;
drStudent["StudentName"] = "Akbar";
drStudent["Class"] = "1B";
drStudent["ContactNo"] = "989878679";
dtStudents.Rows.Add(drStudent);

dtStudents.Rows.Add(new object[] { 2, "Akabr", "1B", "989777" });
dtStudents.Rows.Add(new object[] { 3, "Amar", "1A", "3453" });
dtStudents.Rows.Add(new object[] { 4, "Amar", "1C", "543534" });
dtStudents.Rows.Add(new object[] { 5, "Antoney", "1A", "54345" });
dtStudents.Rows.Add(new object[] { 6, "Bindhu", "1B", "53453" });
dtStudents.Rows.Add(new object[] { 7, "Bindhu", "1D", "3453453" });
dtStudents.Rows.Add(new object[] { 8, "John", "1C", "3245345" });
dtStudents.Rows.Add(new object[] { 9, "Bindhu", "2A", "5345345" });

var results =
    from d in dtStudents.AsEnumerable()
    select d;

dataGridView1.DataSource = results.CopyToDataTable<DataRow>();

3 个答案:

答案 0 :(得分:1)

好吧,你没有真正指定你如何连接到你的数据库所以...无论如何,我们假设你有一些IQueryable被叫,我不知道,classes,或者什么的。然后,您可以执行以下操作:

classes
.GroupBy(
    x => x.Name, 
    (key, values) => new { Name = key, Classes = values.Select(x => x.Class).Distinct())
.Where(x => x.Classes.Take(2).Count() == 2)

答案 1 :(得分:1)

var results = dtStudents.AsEnumerable()
    .GroupBy(
        x => x.Field<string>("StudentName"), // group by student name
        (k, xs) => xs.GroupBy(
            x1 => x1.Field<string>("Class"), // group by class
            (k1, xs1) => xs1.First())) // if there are duplicates, take only the first
    .Where(x => x.Count() >= 2) // remove if student only has one class
    .SelectMany(x => x); // flatten back to a single collection

dataGridView1.DataSource = results.CopyToDataTable<DataRow>();

答案 2 :(得分:1)

我会这样做:

Public Sub MoveToFolder()

Dim objSelection As Selection
Set objSelection = Application.ActiveExplorer.Selection

Dim iSelected As Integer, iMoved As Integer
iSelected = objSelection.Count 'Get a total for output message

Dim StrOutput As String, StrUnmoved As String, StrName As String
StrUnmoved = "Unmoved Item Count by Sender" & vbNewLine & "============================"

Dim objNS As NameSpace
Dim objParentFolder As Folder, objSubFolder As Folder, objDestFolder As Folder
Dim BFound As Boolean, iLoc As Integer
Set objNS = Application.GetNamespace("MAPI")
Set objParentFolder = objNS.GetDefaultFolder(olFolderInbox)

'Only execute code if the parent folder has subfolders
If objParentFolder.Folders.Count > 0 Then
    'Loop through all selected items
    For Each Item In objSelection
        If Item.Class = 43 Then
            'This is an email.
            BFound = False
            StrName = GetSenderName(Item.SenderName)
            For Each objSubFolder In objParentFolder.Folders
                If objSubFolder.Folders.Count > 0 Then
                    On Error Resume Next
                    Set objDestFolder = Nothing
                    Set objDestFolder = objSubFolder.Folders(StrName)
                    On Error GoTo 0
                    If Not objDestFolder Is Nothing Then
                        'Folder found.
                        Item.Move objDestFolder
                        iMoved = iMoved + 1
                        BFound = True
                        Exit For
                    End If
                End If
            Next
            If Not BFound Then
                'Sender folder not found. Check if we have already logged this sender.
                iLoc = 0
                iLoc = InStr(1, StrUnmoved, StrName)
                If iLoc > 0 Then
                    'Existing sender name. Increment current total.
                    StrUnmoved = Left(StrUnmoved, iLoc + Len(StrName) + 1) & _
                    Format(CInt(Mid(StrUnmoved, iLoc + Len(StrName) + 2, 5)) + 1, "00000") & Right(StrUnmoved, Len(StrUnmoved) - iLoc - Len(StrName) - 6)
                Else
                    'New sender name.
                    StrUnmoved = StrUnmoved & vbNewLine & StrName & ": 00001"
                End If
            End If
        End If
    Next

    If iMoved = iSelected Then
        StrOutput = "All " & iSelected & " items moved to appropriate subfolders."
    Else
        'Remove extraneous zeroes
        StrUnmoved = Replace(StrUnmoved, ": 000", ": ")
        StrUnmoved = Replace(StrUnmoved, ": 00", ": ")
        StrUnmoved = Replace(StrUnmoved, ": 0", ": ")
        StrOutput = iMoved & "/" & iSelected & " items moved to appropriate subfolders; see below for unmoved details." & vbNewLine & vbNewLine & StrUnmoved
    End If
    MsgBox StrOutput
Else
    MsgBox "There are no subfolders to the default inbox. Script will now exit."
End If

End Sub

Function GetSenderName(StrFullSender As String) As String

'Only take action if a non-null string is passed
If Len(StrFullSender) > 1 Then
    StrFullSender = Trim(StrFullSender) 'Trim extraneous spaces
    Dim StrOutput As String
    'Find first case of the end of the name
    Dim iChar As Integer
    Dim iCommaCount As Integer
    Dim iSpaceCount As Integer
    For iChar = 1 To Len(StrFullSender)
        Select Case Asc(Mid(StrFullSender, iChar, 1))
            Case 65 To 90, 97 To 122 '192 to 246, 248 to 255 'Include 192-246 and 248-255 if you will receive emails from senders with accents or other symbols in their names
                'No action necessary - this is a letter
            Case 45, 151 'Hyphen or EM Dash - could be a hyphenated name
                If Mid(StrFullSender, IIf(iChar = 1, 1, iChar - 1), IIf(Len(StrFullSender) - iChar > 1, 3, Len(StrFullSender) - iChar + 1)) <> _
                    Trim(Mid(StrFullSender, IIf(iChar = 1, 1, iChar - 1), IIf(Len(StrFullSender) - iChar > 1, 3, Len(StrFullSender) - iChar + 1))) Then Exit For
                    'There is a space on one or both sides of the hyphen. This is a valid stop.
            Case 44
                iCommaCount = iCommaCount + 1
                If iCommaCount > 1 Then Exit For
            Case 32
                iSpaceCount = iSpaceCount + 1
                If iSpaceCount > 1 Then Exit For
            Case 39
                If Mid(StrFullSender, IIf(iChar = 1, 1, iChar - 1), IIf(Len(StrFullSender) - iChar > 1, 3, Len(StrFullSender) - iChar + 1)) <> _
                    Trim(Mid(StrFullSender, IIf(iChar = 1, 1, iChar - 1), IIf(Len(StrFullSender) - iChar > 1, 3, Len(StrFullSender) - iChar + 1))) Then Exit For
                    'There is a space on one or both sides of the apostrophe. This is a valid stop.
            Case Else
                Exit For
        End Select
    Next

    StrOutput = Trim(Left(StrFullSender, iChar - 1))

    GetSenderName = StrOutput
End If

End Function