Link to home
Create AccountLog in
Avatar of lulu50
lulu50Flag for United States of America

asked on

Linq Data Range

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?
Avatar of it_saige
it_saige
Flag of United States of America image

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-
Avatar of lulu50

ASKER

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
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 -User generated image-saige-
Avatar of lulu50

ASKER

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

Avatar of lulu50

ASKER

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.
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-
Avatar of lulu50

ASKER

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();
Avatar of lulu50

ASKER

 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

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-
Avatar of lulu50

ASKER

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())"
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-
Avatar of lulu50

ASKER

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)
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-
Avatar of lulu50

ASKER

Happy Valentines Day!!!

I appreciate your help on this.

it is very hard function and I'm new to MVC C#.
Avatar of lulu50

ASKER

yes please

exact range matches letters and all
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 -User generated imageIn 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-
BTW Happy Valentines to you as well.
Avatar of lulu50

ASKER

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

ASKER CERTIFIED SOLUTION
Avatar of it_saige
it_saige
Flag of United States of America image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Avatar of lulu50

ASKER

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
Avatar of lulu50

ASKER

it_saige

you are an angle and genius!!!

I can't thank you enough

I'm speechless

Thank you my friend!!!!