Home > Blockchain >  Using LINQ to check if a string contains a list of strings or characters
Using LINQ to check if a string contains a list of strings or characters

Time:10-06

I've seen this question asked in different ways (check if a list contains a certain string or whether a string contains any given character) but I need something else.

The programme I'm working on is Poker-related and displays list of poker hands in the format [rank][suit], e.g. AhKd5h3c, in multiple DataGridViews.

Right now, I have this rudimentary textbox filter in place which is working fine.

for (int i = 0; i < allFilteredRows.Count; i  )
{
     allFilteredRows[i] = new BindingList<CSVModel>(allRows[i].Where
    (x => x.Combo.Contains(txtHandFilter.Text)).ToList());          
} 

allFilteredRows is the data source for my DataGridViews. allRows is the unfiltered list of hands from an SQL database. Combo is an individual poker hand.

That only filters for the exact sequence of characters in the textbox, though. What I want is to filter for each rank and suit individually. So if the user types 'AK', all combos that contain (at least) one ace and one king should be displayed. If the input is 'sss', it should filter for all hands with at least three spades. The order of the characters should not matter ('KA' is equal to 'AK') but every character needs to be included and ranks and suits can be combined, e.g. AKh should filter for all hands with at least one ace and the king of hearts.

This goes beyond my knowledge of LINQ so I'd be grateful for any help.

CodePudding user response:

  1. Convert your filter string to List of cards (from what I see, each item is length of 2 if 2nd char is small, length of 1 otherwise).

  2. Use GroupBy to get count of each card, so you should have struct { "K", 3 } instead of "KKK". https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.groupby?view=net-5.0

  3. Repeat on each hand (I assume, that each hand is List instead of just "AhKd5h3c" string)

  4. Iterate through hands checking if it contains all items from p2 output (I assume that { "K", 3 } should return combo that has 4 "K" as well:

    public bool Match(object GroupedCombo, object filter)
    {
        foreach (var item in filter)
        {
            if (!GroupedCombo.Contains(x => x.Card==filter.Card && x.Count>=filter.Count))
                return false;
        }
        return true;
    }
    

CodePudding user response:

It sounds like you want to evaluate multiple conditions for your filter...

The conditions that you need to evaluate look like they are going to require you to parse through a string and extrapolate representations of card combinations. Problem here is it doesn't have any delimiters.

For my suggestion you will need them:

for (int i = 0; i < allFilteredRows.Count; i  )
{
     allFilteredRows[i] = new BindingList<CSVModel>(allRows[i].Where
    (x => txtHandFilter.Text.Split(" ").All(y => x.Combo.Contains(y)).ToList());          
} 

It the textbox you should have the card combos separated by spaces.

You could find some other way to delimit the txtHandFilter if you like, but I think this answers your base question.

  • Related