How do you search through a datatable?

glasswizzard

Well-known member
Joined
Nov 22, 2019
Messages
126
Programming Experience
Beginner
Could someone give me a rundown on how to search through a datatable looking for matching data please. I made this image of a simple table:

NumberGridExample.png


I forgot to add column headers but lets say the headers are the letters A, B, C, and D. When I execute the search I want the numbers to be examined and any that are the same are to be reported like "AA matches AD and DA with 4. AB matches ED with 9. AC matches CA and DB with 5" etc

The number of columns will never change but the rows will increase over time. I'm only asking about how to implement the search functionality, not about showing the results or anything else (the other stuff may pop up in it's own thread at some point), I just want this thread to be laser focused on that one aspect of this.

Thanks
 
Have you tried the brute force approach of just checking pairs?

Pseudo-code:
C#:
for (int row = 0; row < rowCount; row++)
{
    for (int col = 0; col < colCount; col++)
    {
        value = arr[row][col];

        startCol = col + 1;
        for (int i = row; i < rowCount; i++)
        {
            for (int j = startCol; j < colCount; col++)
            {
                if (arr[i][j] == value)
                    record value match between i,j and row,col
            }
            startCol = 0;
        }
    }
}
 
Last edited:
There are more sophisticated approaches by using a dictionary or hash table.
 
And since I'm waiting for something else to complete, here's the pseudo-code for a dictionary or hash table approach:
C#:
entries = new Dictionary<int, List<Coordinates>();
for(int row = 0; row < rowCount; row++)
{
    for (int col = 0; col < colCount; col++)
        entries[arr[row][col]].Add(new Coordinate(row, col));
}

foreach(var value in entries.Keys)
{
    if (entries[value].Count > 1)
        Print coordinates found in entries[value]
}
 
One more thing, I now realize I'm displaying the result wrong, instead of "AA matches AD and DA with 4. AB matches ED with 9. AC matches CA and DB with 5" it should be like this "4: AA, AD (DA is skipped since it's the same). 9: AB, ED. 5: CA, DB."

Let me know if I'm wrong or if there's a simpler way but I have an idea how this would be stored throughout the search, by using a Dictionary<int, List<customCoordinates>>. The first column and the headers will be strings and these strings will be the "coordinates" of the int, so when a match is found the int becomes the key, the strings are the value and if at a later point in the search more matches to that int are found the coordinate strings can simply added to list<customCoordinates> at the appropriate int key.

I am assuming that there isn't a object already that can be used forthis purpose so making a custom coordinates class based on two strings is the way to go right?
 
I love Tuples because they are so convenient for stuff like this. Originally they were most commonly used in game development, but they are now being used more and more in general applications. You can use the overloads if you want to have loads of different objects with different outcomes.

Hmm, assuming this is related to your other recent thread, if "A" has multiple possibilities or outcomes, then overloading Tuples will be of good use especially if you have a Dictionary of string, Tuple:
C#:
            var x = Tuple.Create<object, object, object, object, object, object>(null, null, null, null, null, null);
            Dictionary<string, Tuple<object, object, object, object, object, object>> d = new Dictionary<string, Tuple<object, object, object, object, object, object>>();
            d.Add("A", x);
 
How are they the same? AD is is row 1, column 4, while DA is row 4, column 1.

Eh, your right they're not the same, oops :)

I'm gonna brush up on tuples, specifically overloading them, your example looks more complicated then the tuple usage I've seen so far.
 
There is not a lot to explain. This is simply creating the tuple, and this :
C#:
Tuple.Create<object, object, object, object, object, object>(null, null, null, null, null, null);
Is the same as this :
C#:
Tuple.Create<object, object>(null, null);
Except this is easier to use. Since it's not overloaded and it requires you to insert your own object and values.

As per @JohnH other code on your other topic. He had : var methods = new Dictionary<string, Action>()

C#:
Dictionary<string, Tuple<object, object>> d = new Dictionary<string, Tuple<object, object>>();
So when you declare your dictionary, you have a Dictionary<string, Tuple<Action, Action>>();
But your tuple on this post has only two values, but in my example above, you could overload it to have many values for the tuple, but you also need to replace the objects with Action's. Just as this is overloaded :

C#:
            var x = Tuple.Create<object, object, object, object, object, object>(null, null, null, null, null, null);
            Dictionary<string, Tuple<object, object, object, object, object, object>> d = new Dictionary<string, Tuple<object, object, object, object, object, object>>();
            d.Add("A", x);
You would need to take the objects out and replace them with Action's and provide the methods to call. Replace null with the values you want to store in the Tuple.
Where I have object, would be a variety of Actions instead, just as JohnH demonstrated above.
So when you add your String and Tuple to your dictionary, it is done like this :
C#:
d.Add("A", x);
Where x is your overloaded Tuple containing your different variations of your Methods to call that correspond to the dictionary Key "A".

Run the code in a debugger and you will see how it works. Debugging link in my signature should you need to refresher on a tutorial.
 
Imagine you have a box named A, and box A can hold 2 objects (box A is also your Dictionary). So you put two smaller boxes into the big box. So now box A consists of box B and C which are the smaller boxes. Where box B is your dictionary key, your string, and box C is your Tuple. Box C allows you to store lots of smaller little items inside it. (Those smaller items are your Tuple values.) These items are your method, or action calls. Draw what I am explaining on a piece of paper, and look at it, and then it will and should make more sense when it comes to understanding storing objects inside of objects in C#, and taking this approach will better help you understand object orientation programming concepts that little bit better.

Hope that quick analogy helps.
 
And since I'm waiting for something else to complete, here's the pseudo-code for a dictionary or hash table approach:
C#:
entries = new Dictionary<int, List<Coordinates>();
for(int row = 0; row < rowCount; row++)
{
    for (int col = 0; col < colCount; col++)
        entries[arr[row][col]].Add(new Coordinate(row, col));
}

foreach(var value in entries.Keys)
{
    if (entries[value].Count > 1)
        Print coordinates found in entries[value]
}

I'm trying to do this but my data is in a datatable not an array. I've been trying for ages to figure how to copy the whole thing into a 2d array so that my situation more closely matches your code. Could you tell or show me how to copy it into an array?
 
Last edited:
Back
Top Bottom