We help IT Professionals succeed at work.

Linq Data Range

lulu50
lulu50 asked
on
Hi,

I need your help please!!!

 I want to say if the user enter in GroupTxt a range from 10 -30 the linq query will return the result within that range.


HTML Code
<select name="GroupListID" class="btn btn-default dropdown-toggle" id="GroupListID">
                            <option value="">Select an Option</option>
                                    <option value="3">Dx</option>
                                    <option value="5">Group ID</option>
                                    <option value="4">NPI</option>
                                    <option value="6">Plan Code</option>
                                    <option value="1">Px</option>
                        </select>


                         @Html.TextBoxFor(x => x.GroupTxt, new { @class = "form-control", @style = "width:100%" })

Open in new window



Database
Table: RuleDetail
if (model.SelectedGroupID != null && model.GroupTxt != null)
                     list = list.Where(x => model.GroupTxt.Any(m => Equals(x.ConditionAttributesAndValues, m)));
              
                      // here I want to say 
                      //  and 
                      // and if the user enter a range in the textbox then filter all that are within the range.

Open in new window



ConditionAttributesAndValues is varchar(1000)

the data inside the ConditionAttributesAndValue looks like this:

<br> IF Dx = aa (299.00,<br>299.01,<br>299.80,<br>299.81,<br>299.90,<br>299.91,<br>99999)  <br> AND Dx Between Range (10 - 30) <br>(aa22)<br>"aa55"<br>

Open in new window


so is there a way to search for Dx range and see if what the user enter in the textbox is within the range in the database field called ConditionAttributesAndValue?
Comment
Watch Question

it_saigeDeveloper
BRONZE EXPERT
Distinguished Expert 2019

Commented:
Let me paraphrase to see if I understand your question.

If the user enters text into the text box; e.g. - 10 - 30, you want to see if the text enter is contained inside Dx Between Range (x - x ) in the ConditionAttributesAndValue?

-saige-
lulu50Web application

Author

Commented:
yes that is correct

so if the user enter 10-30 in a texbox

and the ConditionAttributesAndValue has the following data

Dx Between Range (2-40)  the record should come up
because it is in the range of what the user enter 10-30
it_saigeDeveloper
BRONZE EXPERT
Distinguished Expert 2019

Commented:
Quick and dirty, you could do something like:
static bool InRange(string range, string source)
{
    var bookends = range.Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
    var _range = Enumerable.Range(bookends.First(), bookends.LastOrDefault() == 0 ? 1 : bookends.Last());
    var start = source.IndexOf("Dx Between Range (") + "Dx Between Range (".Length;
    var end = source.IndexOf(")", start);
    var values = source.Substring(start, end - start).Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
    var sourceRange = Enumerable.Range(values.First(), values.LastOrDefault() == 0 ? 1 : values.Last());
    return _range.Intersect(sourceRange).Any();
}

Open in new window

Proof of concept -
using System;
using System.Linq;

namespace EE_Q29172573
{
    class Program
    {
        static void Main(string[] args)
        {
            var attributes = new[] 
            { 
                "<br> IF Dx = aa (299.00,<br>299.01,<br>299.80,<br>299.81,<br>299.90,<br>299.91,<br>99999)  <br> AND Dx Between Range (10 - 30) <br>(aa22)<br>\"aa55\"<br>",
                "<br> IF Dx = aa (299.00,<br>299.01,<br>299.80,<br>299.81,<br>299.90,<br>299.91,<br>99999)  <br> AND Dx Between Range (2 - 40) <br>(aa22)<br>\"aa55\"<br>",
                "<br> IF Dx = aa (299.00,<br>299.01,<br>299.80,<br>299.81,<br>299.90,<br>299.91,<br>99999)  <br> AND Dx Between Range (2 - 8) <br>(aa22)<br>\"aa55\"<br>",
                "<br> IF Dx = aa (299.00,<br>299.01,<br>299.80,<br>299.81,<br>299.90,<br>299.91,<br>99999)  <br> AND Dx Between Range (40 - 70) <br>(aa22)<br>\"aa55\"<br>"
            };

            foreach (var item in attributes.Where(x => InRange("10 - 30", x)))
            {
                Console.WriteLine(item);
            }
            Console.ReadLine();
        }

        static bool InRange(string range, string source)
        {
            var bookends = range.Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
            var _range = Enumerable.Range(bookends.First(), bookends.LastOrDefault() == 0 ? 1 : bookends.Last());
            var start = source.IndexOf("Dx Between Range (") + "Dx Between Range (".Length;
            var end = source.IndexOf(")", start);
            var values = source.Substring(start, end - start).Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
            var sourceRange = Enumerable.Range(values.First(), values.LastOrDefault() == 0 ? 1 : values.Last());
            return _range.Intersect(sourceRange).Any();
        }
    }
}

Open in new window

Which produces the following output -Capture.PNG-saige-
lulu50Web application

Author

Commented:
it_saige,,

I'm not sure what to do.

I have a textbox called Grouptxt
if the user enter in the textbox number 18 - 20
I should get back recordID 1 and 3 and 5 as a result.

RuleDetail table

RecordID               ConditionAttributesAndValues

1                           Rule222  (Func1) <br> AND Dx Between Range (17 - 20)

2                           Rule222  (Route MIS)

3                           ww  (For Every DX in 18)

4                           <p>sdf (Exit Px)</p>AND Px Between Range (50 - 100)

 5                         <br> IF Dx = aa (299.00,<br>299.01,<br>299.80,<br>299.81,<br>299.90,<br>299.91,<br>99999)  <br> AND
                             Dx Between Range (10 - 30) <br>(On Event)<br>"aa55"<br>

This is my code ;


 public List<RuleDetail> RuleDetailList(CABRSearchRules model)
        {
            List<RuleDetail> modelList = new List<RuleDetail>();

            IEnumerable<CABR_RuleDetail> list = new List<CABR_RuleDetail>();
            IEnumerable<CABR_HistoryRuleDetail> Historylist = new List<CABR_HistoryRuleDetail>();

            if (model.SelectedCurrentOrHistoryID == 1) //Current
            {
                list = _unitOfWorkCABusinessRules.RuleDetailRepo.GetAll().ToList();

                //Filter Status
                if (model.SelectedStatus != null)
                    list = list.Where(x => x.isActive == model.SelectedStatus);

                //Filter Created Date
                if (model.FromCreatedDate.ToString() != "1/1/0001 12:00:00 AM" && model.ToCreatedDate.ToString() != "1/1/0001 12:00:00 AM")
                    list = list.Where(x => x.CreatedDate.Date >= model.FromCreatedDate.Date && x.CreatedDate.Date <= model.ToCreatedDate.Date);

                //Filter Migration Date
                if (model.FromMigrationDate.ToString() != "1/1/0001 12:00:00 AM" && model.ToMigrationDate.ToString() != "1/1/0001 12:00:00 AM")
                    list = list.Where(x => x.MigrationDate.Date >= model.FromMigrationDate.Date && x.MigrationDate.Date <= model.ToMigrationDate.Date);

                //Filter Migration Date
                if (model.RuleDescription != null)
                    list = list.Where(x => x.RuleDescription.Contains(model.RuleDescription));

                //Filter Condition Attributes And Values
                if (model.ConditionAttributesAndValues != null)
                    list = list.Where(x => x.ConditionAttributesAndValues.Contains(model.ConditionAttributesAndValues));

                   //Filter Selected Function
                if (model.SelectedFunction != null)
                    list = list.Where(x => model.SelectedFunction.Any(x.ConditionAttributesAndValues.Contains));

                //Filter FunctionTxt
                if (model.FunctionTxt != null)
                    list = list.Where(x => x.ConditionAttributesAndValues.ToLower().Contains(model.FunctionTxt.ToLower()));

                //Filter Selected Group
                if (model.SelectedGroup != null)
                    list = list.Where(x => model.SelectedGroup.Any(x.ConditionAttributesAndValues.Contains));

                //Filter Group Txt
                if (model.GroupTxt != null && !model.GroupTxt.Contains("-"))
                    list = list.Where(x => x.ConditionAttributesAndValues.ToLower().Contains(model.GroupTxt.ToLower()));

                 //Here I want to say get all the records that are within the "Range" that is in the field ConditionAttirbutesAndValues  
              
            }
         
            var GetRuleset = _unitOfWorkCABusinessRules.RuleSetRepo.GetAll()
                .Where(x => x.IsActive == true).ToList();

            var GetRuleIdentifier = _unitOfWorkCABusinessRules.RuleIdentifierRepo.GetAll()
                .Where(x => x.IsActive == true).ToList();

            modelList = list.ToList().Select(x => new RuleDetail
            {
                Status = (Boolean)x.isActive,
                RuleSet = GetRuleset.Where(a => a.RuleSetId == x.RuleSetId).FirstOrDefault().RuleSet,
                RuleIdentifier = GetRuleIdentifier.Where(a => a.RuleIdentifierId == x.RuleIdentifierId).FirstOrDefault().RuleIdentifier,
                Versions = x.Version,
                Environments = x.Environment,
                CommitID = x.CommitID,
                CommitDescription = x.CommitDescription,
                RuleDescription = x.CommitDescription,
                ConditionAttributesAndValues = x.ConditionAttributesAndValues,
                ActionAttributesAndValues = x.ActionAttributesAndValues,
                CommentOrNotes = x.CommentOrNotes,
                MigrationDate = x.MigrationDate,
                CreatedDate = x.CreatedDate,
                SubmitterLastNameFirstName = x.SubmitterLastNameFirstName,
                CQTicket = x.CQTicket
            }).ToList();

            return modelList;

        }

Open in new window

lulu50Web application

Author

Commented:
if the user enter in the textbox range 18 -20   or if they just enter a number 18

I should get back recordID 1 and 3 and 5 as a result.
it_saigeDeveloper
BRONZE EXPERT
Distinguished Expert 2019

Commented:
Assuming that model.GroupTxt is the textbox data, line 51 should go something like this perhaps:
if (model.GroupTxt != null && model.GroupTxt.Contains("-"))
    list = list.Where(x => InRange(model.GroupTxt, x));

Open in new window

And then somewhere else in your codebase (maybe even after the method you are working in) place the InRange method:
private bool InRange(string range, string source)
{
    var bookends = range.Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
    var _range = Enumerable.Range(bookends.First(), bookends.LastOrDefault() == 0 ? 1 : bookends.Last());
    var start = source.IndexOf("Dx Between Range (") + "Dx Between Range (".Length;
    var end = source.IndexOf(")", start);
    var values = source.Substring(start, end - start).Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
    var sourceRange = Enumerable.Range(values.First(), values.LastOrDefault() == 0 ? 1 : values.Last());
    return _range.Intersect(sourceRange).Any();
}

Open in new window

-saige-
lulu50Web application

Author

Commented:
I put in my textbox "GroupTx" 18-20

I got an error that says this:

An exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll but was not handled in user code

Additional information: Length cannot be less than zero.


Length cannot be less than zero.
Parameter name: length
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

 Exception Details: System.ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length

Source Error:

it says: end is -1 and it cannot be less than zero
the error is on line 2344  "end" = -1

Line 2342:            var start = source.IndexOf("Dx Between Range (") + "Dx Between Range (".Length;
Line 2343:            var end = source.IndexOf(")", start);
Line 2344:            var values = source.Substring(start, end - start).Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
Line 2345:            var sourceRange = Enumerable.Range(values.First(), values.LastOrDefault() == 0 ? 1 : values.Last());
Line 2346:            return _range.Intersect(sourceRange).Any();
lulu50Web application

Author

Commented:
 I put x.ToString() because I got an error that says 

Cannot convert 'CareAdvanceBusinessRules.Data.CABR_RuleDetail' to 'String'


                if (model.GroupTxt != null && model.GroupTxt.Contains("-"))
                    list = list.Where(x => InRange(model.GroupTxt, x.ToString()));

Open in new window


      private bool InRange(string range, string source)
        {
            var bookends = range.Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
            var _range = Enumerable.Range(bookends.First(), bookends.LastOrDefault() == 0 ? 1 : bookends.Last());
            var start = source.IndexOf("Dx Between Range (") + "Dx Between Range (".Length;
            var end = source.IndexOf(")", start);
            var values = source.Substring(start, end - start).Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
            var sourceRange = Enumerable.Range(values.First(), values.LastOrDefault() == 0 ? 1 : values.Last());
            return _range.Intersect(sourceRange).Any();
        }

Open in new window

it_saigeDeveloper
BRONZE EXPERT
Distinguished Expert 2019

Commented:
My mistake:
if (model.GroupTxt != null && model.GroupTxt.Contains("-"))
    list = list.Where(x => InRange(model.GroupTxt, x.ConditionAttributesAndValues));

Open in new window

Also might want to add a check to ensure that our start and end make sense;
private bool InRange(string range, string source)
{
    var bookends = range.Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
    var _range = Enumerable.Range(bookends.First(), bookends.LastOrDefault() == 0 ? 1 : bookends.Last());
    var start = source.IndexOf("Dx Between Range (") + "Dx Between Range (".Length;
    var end = source.IndexOf(")", start);
    if (start == -1 || end == -1)
    {
        return false;
    }
    var values = source.Substring(start, end - start).Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
    var sourceRange = Enumerable.Range(values.First(), values.LastOrDefault() == 0 ? 1 : values.Last());
    return _range.Intersect(sourceRange).Any();
}

Open in new window

-saige-
lulu50Web application

Author

Commented:
I'm getting this error

I put in the input box 18-20

then I got an error that says:

{"Input string was not in a correct format."}

the error pointing to this line

 var values = source.Substring(start, end - start).Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);


"Convert.ToInt32(x.Trim())"
it_saigeDeveloper
BRONZE EXPERT
Distinguished Expert 2019

Commented:
This means that the value in x is not an integer.  So you need to debug and determine where the issue is.  My assumptions were that where ever you have 'Dx Between Range (' it was followed by either a range; e.g. - 1 - 10, separated by a hyphen.  But I also made it to where if there was only one integer it would select a range of one representing the integer itself.

If you can provide me the contents of your list, I can try to help determine what the issue is.

-saige-
lulu50Web application

Author

Commented:
it_saige,



I'm debugging it but I don't know how to fix the error.

How can I say this
1. if ConditionAttributesAndValues has "Range ("  or  (Range (" in the record
2. go to the function InRange

 list = list.Where(x => x.ConditionAttributesAndValues.ToLower().Contains("Range ("));
then go to the function InRange
and find the range it.


string range is returning this: 
F05-F09

string source is returning this: 
 <br> IF Px IN Actigraphy (0089T,<br>0124T,<br>53860,<br>90620,<br>96904,<br>J2325,<br>M0075,<br>S8040,<br>S8940,) 

the error is happening on this line: 
var bookends = range.Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);

Convert.ToInt32(x.Trim()))  - > that is where the error 


 private bool InRange(string range, string source)
        {
            var bookends = range.Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
            var _range = Enumerable.Range(bookends.First(), bookends.LastOrDefault() == 0 ? 1 : bookends.Last());
            var start = source.IndexOf("Dx Between Range (") + "Dx Between Range (".Length;
            var end = source.IndexOf(")", start);
            if (start == -1 || end == -1)
            {
                return false;
            }
            var values = source.Substring(start, end - start).Split('-').Select(x => Convert.ToInt32(x.Trim())).OrderBy(x => x);
            var sourceRange = Enumerable.Range(values.First(), values.LastOrDefault() == 0 ? 1 : values.Last());
            return _range.Intersect(sourceRange).Any();
        }

Open in new window




This is how my data in the database:

RuleDetailID                            ConditionAttributesAndValues

16                                              <br> IF Px IN Actigraphy
                                                   (0089T,<br>0124T,<br>53860,<br>90620,<br>96904,<br>J2325,<br>M0075,<br>S8040,<br>S8940,)

17                                              IF Dx IN Acute_Pancreatitis
                                                  <br>K85.12,<br>K85.2,<br>K85.20,<br>K85.21,<br>K85.3)  Select <br> AND Px Between Range (M4445 - M5644)

18                                             Dx Between Range (1 - 30)

19                                             IF Dx IN aa (299.00,<br>299.01,<br>299.80,<br>299.81,<br>299.90,<br>299.91,<br>99999)&nbsp;&nbsp;<br>  
                                                 <br> AND Dx Between Range (F01 - F99)

20                                            IF Px Not IN Actigraphy (0089T,<br>0124T,<br>S8040,<br>S8940,) <br> AND NPI IN NPI_001 (1417941774)
it_saigeDeveloper
BRONZE EXPERT
Distinguished Expert 2019

Commented:
The InRange method won't work with that dataset because the ranges include letters.  And I assume that the letters are significant, so if your user enters in M30 - M50; if you strip off the letters, you may get unintended ranges returned; e.g. - F24 - F31, S40 - S80, etc, etc,  I can make it work, but just need to know if you want exact range matches letters and all?

-saige-
lulu50Web application

Author

Commented:
Happy Valentines Day!!!

I appreciate your help on this.

it is very hard function and I'm new to MVC C#.
lulu50Web application

Author

Commented:
yes please

exact range matches letters and all
it_saigeDeveloper
BRONZE EXPERT
Distinguished Expert 2019

Commented:
I redid the method and tweaked the search a little bit.  In order to ensure that the data matches the string you are looking for, I stripped the whitespace before comparing but left the strings themselves intact.

So new methods:
private bool InRange(string search, string source)
{
    var result = default(bool);
    var start = default(int);
    var end = default(int);
    var searchRange = default(Dictionary<string, IEnumerable<int>>);
    var sourceRange = default(Dictionary<string, IEnumerable<int>>);
    try
    {
        start = source.IndexOf("BetweenRange(", StringComparison.OrdinalIgnoreCase) + "BetweenRange(".Length;
        end = source.IndexOf(")", start);
        searchRange = GetRangeDictionary(search);
        sourceRange = GetRangeDictionary(source.Substring(start, end - start));
        result = (from lhs in searchRange
                    from rhs in sourceRange
                    where Equals(lhs.Key, rhs.Key)
                    select lhs.Value.Intersect(rhs.Value)).Any();
    }
    catch (Exception ex)
    {
        // Ideally you would log some message to let you know that this failed
        //Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
        result = false;
    }

    return result;
}

private Dictionary<string, IEnumerable<int>> GetRangeDictionary(string source)
{
    var result = default(Dictionary<string, IEnumerable<int>>);
    try
    {
        result = source.Split('-')
            .Select(x => new KeyValuePair<string, int>(Regex.Match(x, @"\D+")?.Value ?? string.Empty, Convert.ToInt32(Regex.Match(x, @"\d+")?.Value ?? "0")))
            .OrderBy(x => x.Value)
            .GroupBy(x => x.Key)
            .Select(x => new KeyValuePair<string, IEnumerable<int>>(x.Key, Enumerable.Range(x.First().Value, x.LastOrDefault().Value == 0 ? 1 : x.Last().Value - x.First().Value + 1)))
            .ToDictionary(x => x.Key, x => x.Value);
    }
    catch (Exception ex)
    {
        // Ideally you would log a message to let you know that this failed
        //Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
        result = new Dictionary<string, IEnumerable<int>>();
    }

    return result;
}

Open in new window

Proof of concept -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace EE_Q29172573
{
    class Program
    {
        static void Main(string[] args)
        {
            var attributes = new[] 
            {
                "<br> IF Px IN Actigraphy (0089T,<br>0124T,<br>53860,<br>90620,<br>96904,<br>J2325,<br>M0075,<br>S8040,<br>S8940,)",
                "<br> IF Dx IN Acute_Pancreatitis <br>K85.12,<br>K85.2,<br>K85.20,<br>K85.21,<br>K85.3)  Select<br> AND Px Between Range(M4445 - M5644) < br>(aa22)<br>\"aa55\"<br>",
                "<br> Dx Between Range (1 - 30) <br>(aa22)<br>\"aa55\"<br>",
                "<br> F Dx IN aa (299.00,<br>299.01,<br>299.80,<br>299.81,<br>299.90,<br>299.91,<br>99999)&nbsp;&nbsp;<br> AND Dx Between Range (F01 - F99) <br>(aa22)<br>\"aa55\"<br>",
                "<br>  IF Px Not IN Actigraphy (0089T,<br>0124T,<br>S8040,<br>S8940,) <br> AND NPI IN NPI_001 (1417941774) <br>(aa22)<br>\"aa55\"<br>"
            };

            foreach (var search in new[] { "10 - 30", "F98 - F200", "M4976 - M6000" })
            {
                foreach (var item in attributes.Where(x => x.Replace(" ", "").IndexOf("BetweenRange(", StringComparison.OrdinalIgnoreCase) > -1 ? InRange(search.Replace(" ", ""), x.Replace(" ", "")) : false))
                {
                    Console.WriteLine(item);
                }
            }
            Console.ReadLine();
        }

        static bool InRange(string search, string source)
        {
            var result = default(bool);
            var start = default(int);
            var end = default(int);
            var searchRange = default(Dictionary<string, IEnumerable<int>>);
            var sourceRange = default(Dictionary<string, IEnumerable<int>>);
            try
            {
                start = source.IndexOf("BetweenRange(") + "BetweenRange(".Length;
                end = source.IndexOf(")", start);
                searchRange = GetRangeDictionary(search);
                sourceRange = GetRangeDictionary(source.Substring(start, end - start));
                result = (from lhs in searchRange
                          from rhs in sourceRange
                          where Equals(lhs.Key, rhs.Key)
                          select lhs.Value.Intersect(rhs.Value)).Any();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
                result = false;
            }

            return result;
        }

        static Dictionary<string, IEnumerable<int>> GetRangeDictionary(string source)
        {
            var result = default(Dictionary<string, IEnumerable<int>>);
            try
            {
                result = source.Split('-')
                    .Select(x => new KeyValuePair<string, int>(Regex.Match(x, @"\D+")?.Value ?? string.Empty, Convert.ToInt32(Regex.Match(x, @"\d+")?.Value ?? "0")))
                    .OrderBy(x => x.Value)
                    .GroupBy(x => x.Key)
                    .Select(x => new KeyValuePair<string, IEnumerable<int>>(x.Key, Enumerable.Range(x.First().Value, x.LastOrDefault().Value == 0 ? 1 : x.Last().Value - x.First().Value + 1)))
                    .ToDictionary(x => x.Key, x => x.Value);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
                result = new Dictionary<string, IEnumerable<int>>();
            }

            return result;
        }
    }
}

Open in new window

Produces the following output -Capture.PNGIn your code change this:
if (model.GroupTxt != null && model.GroupTxt.Contains("-"))
    list = list.Where(x => InRange(model.GroupTxt, x.ConditionAttributesAndValues));

Open in new window

To this:
if (model.GroupTxt != null && model.GroupTxt.Contains("-"))
    list = list.Where(x => InRange(model.GroupTxt.Replace(" ", ""), x.ConditionAttributesAndValues.Replace(" ", "")));

Open in new window

If you want to see if your ConditionAttributeAndValues contains 'Between Range (', you could do something like this:
if (model.GroupTxt != null && model.GroupTxt.Contains("-"))
    list = list.Where(x => x.ConditionAttributesAndValues.Replace(" ", "").IndexOf("BetweenRange(", StringComparison.OrdinalIgnoreCase) > -1 ? InRange(model.GroupTxt.Replace(" ", ""), x.ConditionAttributesAndValues.Replace(" ", "")) : false);

Open in new window

Also don't forget to replace the InRange method with the new one and add the GetRangeDictionary method.

-saige-
it_saigeDeveloper
BRONZE EXPERT
Distinguished Expert 2019

Commented:
BTW Happy Valentines to you as well.
lulu50Web application

Author

Commented:
There's some more to it.

I entered this in the textbox: K90.0 - K90.1

I got the correct return back which is great!!! very happy

then I tried a range from 1 -20

I also got the correct result. very very very happy lol lol

__________________________________________

So we got half of it working great.

ok let say the user enter:  K90.1

I should still be able to pull the record below
because K90.1 is within the range

or if the user enter K85.01
I should see the record below because it is in the list

the data looks like this:

IF Dx IN Acute_Pancreatitis (K85,
K85.0,
K85.00,
K85.01,
K85.02,
K85.1,
K85.10,
K85.11,
K85.12,
K85.2,
K85.20,
K85.21,
K85.22,
K85.3) Select
 AND Dx Between Range (K90.0 - K100)



I made up this record as an example that would be pulled because K90.1 is in Dx list

IF Dx IN aa (299.00,
299.01,
299.80,
299.81,
K90.1,
299.90,
299.91,
99999)  
 AND Dx Between Range (F01 - F99)


there's two ranges Dx or Px should have the same functionality

this is an example of the px

IF Px Not IN Actigraphy (0089T,
0124T,
53860,
90620,
96904,
J2325,
M0075,
S8040,
S8940,)
 AND NPI IN NPI_001 (1417941774)
 AND Px Between Range (10000 - 58999)  

so if the user enter 10020
I should get the record above because it's in the range

or if they enter S8040
I should also get the record above because it's in the list above


It looks great!!! so far

I would never be able to do it without you.  what a great gift you have!!!!

So I'm grateful and thankful to you for sharing your skills and knowledge

 

 if (model.GroupTxt != null && model.GroupTxt.Contains("-"))
                   list = list.Where(x => InRange(model.GroupTxt.Replace(" ", ""), x.ConditionAttributesAndValues.Replace(" ", "")));


 private bool InRange(string search, string source)
        {
            var result = default(bool);
            var start = default(int);
            var end = default(int);
            var searchRange = default(Dictionary<string, IEnumerable<int>>);
            var sourceRange = default(Dictionary<string, IEnumerable<int>>);
            try
            {
                start = source.IndexOf("BetweenRange(", StringComparison.OrdinalIgnoreCase) + "BetweenRange(".Length;
                end = source.IndexOf(")", start);
                searchRange = GetRangeDictionary(search);
                sourceRange = GetRangeDictionary(source.Substring(start, end - start));
                result = (from lhs in searchRange
                          from rhs in sourceRange
                          where Equals(lhs.Key, rhs.Key)
                          select lhs.Value.Intersect(rhs.Value)).Any();
            }
            catch (Exception e)
            {
                // Ideally you would log some message to let you know that this failed
                //Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
                result = false;
            }

            return result;
        }

        private Dictionary<string, IEnumerable<int>> GetRangeDictionary(string source)
        {
            var result = default(Dictionary<string, IEnumerable<int>>);
            try
            {
                result = source.Split('-')
                    .Select(x => new KeyValuePair<string, int>(Regex.Match(x, @"\D+")?.Value ?? string.Empty, Convert.ToInt32(Regex.Match(x, @"\d+")?.Value ?? "0")))
                    .OrderBy(x => x.Value)
                    .GroupBy(x => x.Key)
                    .Select(x => new KeyValuePair<string, IEnumerable<int>>(x.Key, Enumerable.Range(x.First().Value, x.LastOrDefault().Value == 0 ? 1 : x.Last().Value - x.First().Value + 1)))
                    .ToDictionary(x => x.Key, x => x.Value);
            }
            catch (Exception e)
            {
                // Ideally you would log a message to let you know that this failed
                //Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
                result = new Dictionary<string, IEnumerable<int>>();
            }

            return result;
        }

Open in new window

Developer
BRONZE EXPERT
Distinguished Expert 2019
Commented:
For creating the lists I am going to make some assumptions which, if true, are going to be the rules for parsing your searches.

First, all of the lists begin with '(' and end with ')'
Second, all of the lists come before the ranges.
Third, all of the lists are comma separated.
Finally, all of the ranges will begin with 'Between Range (' and end with ')'

Optionally, all of the lists may contain an html page break character '<br>', if found, replace.
Optionally, the ranges are hyphen separated.

The code that I had presented earlier is already allowing single value searches in the ranges and supports single value ranges as well.

If all of these rules are true, then the fix is simple:
private bool InListOrRange(string search, string source)
{
    var result = default(bool);
    var start = default(int);
    var end = default(int);
    var searchRange = default(Dictionary<string, IEnumerable<int>>);
    var sourceRange = default(Dictionary<string, IEnumerable<int>>);
    var list = default(IEnumerable<string>);
    try
    {
        // Replace the whitespace for easier parsing
        search = search.Replace(" ", "");
        source = source.Replace(" ", "");

        // Get our ranges
        start = source.IndexOf("BetweenRange(", StringComparison.OrdinalIgnoreCase) + "BetweenRange(".Length;
        end = source.IndexOf(")", start);
        searchRange = GetRangeDictionary(search);
        sourceRange = GetRangeDictionary(source.Substring(start, end - start));

        // Get our list
        start = source.IndexOf("(") != start ? source.IndexOf('(') + 1 : -1;
        if (start != -1)
        {
            end = source.IndexOf(")", start);
        }
        list = start != -1 ? source.Substring(start, end - start).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Replace("<br>", "")) : new string[] { };

        result = (from lhs in searchRange
                    from rhs in sourceRange
                    where Equals(lhs.Key, rhs.Key)
                    select lhs.Value.Intersect(rhs.Value).Any()).Any(x => x) || list.Any(x => string.Equals(search, x, StringComparison.OrdinalIgnoreCase));
    }
    catch (Exception ex)
    {
        // Ideally we would log something here to let us know this failed.
        //Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
        result = false;
    }

    return result;
}

private Dictionary<string, IEnumerable<int>> GetRangeDictionary(string source)
{
    var result = default(Dictionary<string, IEnumerable<int>>);
    try
    {
        result = source.Split('-')
            .Select(x => new KeyValuePair<string, int>(Regex.Match(x, @"\D+")?.Value ?? string.Empty, Convert.ToInt32(Regex.Match(x, @"\d+")?.Value ?? "0")))
            .OrderBy(x => x.Value)
            .GroupBy(x => x.Key)
            .Select(x => new KeyValuePair<string, IEnumerable<int>>(x.Key, Enumerable.Range(x.First().Value, x.LastOrDefault().Value == 0 ? 1 : x.Last().Value - x.First().Value + 1)))
            .ToDictionary(x => x.Key, x => x.Value);
    }
    catch (Exception ex)
    {
        // Ideally we would log something here to let us know this failed.
        //Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
        result = new Dictionary<string, IEnumerable<int>>();
    }

    return result;
}

Open in new window

Proof of concept -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace EE_Q29172573
{
    class Program
    {
        static void Main(string[] args)
        {
            var attributes = new[] 
            {
                "<br> IF Px IN Actigraphy (0089T,<br>0124T,<br>53860,<br>90620,<br>96904,<br>J2325,<br>M0075,<br>S8040,<br>S8940,)",
                "<br> IF Dx IN Acute_Pancreatitis (<br>K85.12,<br>K85.2,<br>K85.20,<br>K85.21,<br>K85.3)  Select<br> AND Px Between Range(M4445 - M5644) < br>(aa22)<br>\"aa55\"<br>",
                "<br> Dx Between Range (1 - 30) <br>(aa22)<br>\"aa55\"<br>",
                "<br> F Dx IN aa (299.00,<br>299.01,<br>299.80,<br>299.81,<br>299.90,<br>299.91,<br>99999)&nbsp;&nbsp;<br> AND Dx Between Range (F01 - F99) <br>(aa22)<br>\"aa55\"<br>",
                "<br>  IF Px Not IN Actigraphy (0089T,<br>0124T,<br>S8040,<br>S8940,) <br> AND NPI IN NPI_001 (1417941774) <br>(aa22)<br>\"aa55\"<br>",
                "IF Dx IN aa (299.00,299.01,299.80,299.81,K90.1,299.90,299.91,99999) AND Dx Between Range(F01 -F99)",
                "IF Px Not IN Actigraphy (0089T,0124T,53860,90620,96904,J2325,M0075,S8040,S8940,) AND NPI IN NPI_001(1417941774) AND Px Between Range(10000 - 58999)",
                "IF Dx IN Acute_Pancreatitis (K85,K85.0,K85.00,K85.01,K85.02,K85.1,K85.10,K85.11,K85.12,K85.2,K85.20,K85.21,K85.22,K85.3) Select AND Dx Between Range (K90.0 - K100)"
            };

            foreach (var search in new[] { "10 - 30", "F98 - F200", "M4976 - M6000", "K90 - K90.1", "1 - 20", "K90.1", "K85.01", "K90.1", "10020", "S8040" })
            {
                Console.WriteLine($"Searching for: {search}");
                foreach (var item in attributes.Where(x => InListOrRange(search, x)))
                {
                    Console.WriteLine($"Found search in - {item}");
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }

        static bool InListOrRange(string search, string source)
        {
            var result = default(bool);
            var start = default(int);
            var end = default(int);
            var searchRange = default(Dictionary<string, IEnumerable<int>>);
            var sourceRange = default(Dictionary<string, IEnumerable<int>>);
            var list = default(IEnumerable<string>);
            try
            {
                // Replace the whitespace for easier parsing
                search = search.Replace(" ", "");
                source = source.Replace(" ", "");

                // Get our ranges
                start = source.IndexOf("BetweenRange(", StringComparison.OrdinalIgnoreCase) + "BetweenRange(".Length;
                end = source.IndexOf(")", start);
                searchRange = GetRangeDictionary(search);
                sourceRange = GetRangeDictionary(source.Substring(start, end - start));

                // Get our list
                start = source.IndexOf("(") != start ? source.IndexOf('(') + 1 : -1;
                if (start != -1)
                {
                    end = source.IndexOf(")", start);
                }
                list = start != -1 ? source.Substring(start, end - start).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Replace("<br>", "")) : new string[] { };

                result = (from lhs in searchRange
                         from rhs in sourceRange
                         where Equals(lhs.Key, rhs.Key)
                         select lhs.Value.Intersect(rhs.Value).Any()).Any(x => x) || list.Any(x => string.Equals(search, x, StringComparison.OrdinalIgnoreCase));
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
                result = false;
            }

            return result;
        }

        static Dictionary<string, IEnumerable<int>> GetRangeDictionary(string source)
        {
            var result = default(Dictionary<string, IEnumerable<int>>);
            try
            {
                result = source.Split('-')
                    .Select(x => new KeyValuePair<string, int>(Regex.Match(x, @"\D+")?.Value ?? string.Empty, Convert.ToInt32(Regex.Match(x, @"\d+")?.Value ?? "0")))
                    .OrderBy(x => x.Value)
                    .GroupBy(x => x.Key)
                    .Select(x => new KeyValuePair<string, IEnumerable<int>>(x.Key, Enumerable.Range(x.First().Value, x.LastOrDefault().Value == 0 ? 1 : x.Last().Value - x.First().Value + 1)))
                    .ToDictionary(x => x.Key, x => x.Value);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Message: {ex.Message}{Environment.NewLine}{ex.StackTrace}");
                result = new Dictionary<string, IEnumerable<int>>();
            }

            return result;
        }
    }
}

Open in new window

Produces the following output -Capture.PNGMake sure you replace the current InRange and GetRangeDictionary methods.  As for your code:
if (model.GroupTxt != null && model.GroupTxt.Contains("-"))
    list = list.Where(x => InListOrRange(model.GroupTxt, x.ConditionAttributesAndValues));

Open in new window

-saige-
lulu50Web application

Author

Commented:
it_saige  

You are a genius!!!!!

I'm speechless!!!!!  I can't thank you enough !!!!!!

I want to thank you from all my heart for spending the time with me helping me to solve my problem.

I will never get this without you.

Thank you for 1,000,01  lol lol
lulu50Web application

Author

Commented:
it_saige

you are an angle and genius!!!

I can't thank you enough

I'm speechless

Thank you my friend!!!!