Home > Software engineering >  How to check for overlaps and continue to count sum for the unaccounted elements moving forward (jag
How to check for overlaps and continue to count sum for the unaccounted elements moving forward (jag

Time:09-17

For example I have this array in which later I would need to search through:

private static readonly decimal[] ArrayWithFiveElements = { 0.1m, 0.2m, 0.3m, 0.4m, 0.5m };

And then I have a arrays of ranges that defines which elements to search for:

            decimal[][] ranges =
            {
                new[] { 0.1m, 0.2m },
                new[] { 0.4m, 0.5m },
                new[] { decimal.Zero, decimal.One },
            };

Now what my code should do is return the number of occurences of the elements that match the range criteria. Now if I try to count these ranges without the last array i'll get 4: 0.1m, 0.2m, 0.4m and 0.5m, but if we try to count it with the last one (which overlaps the previuos two arrays) I will get the result 9: 0.1m, 0.2m, 0.4m, 0.5m, 0.1m, 0.2m, 0.3m 0.4m and 0.5m. What I want in my result is 5: 0.1m, 0.2m, 0.3m, 0.4m, 0.5m .

How can I count through the array and if the array overlaps with some of the elements in the previuos arrays it ignores them, and if there is a uncounted element it will add to the count instead of adding everything multiple times it overlaps.

This is my code so far:

        public static int GetDecimalsCount(decimal[] arrayToSearch, decimal[][] ranges)
        {
            if (arrayToSearch is null)
            {
                throw new ArgumentNullException(nameof(arrayToSearch));
            }
            else if (ranges is null)
            {
                throw new ArgumentNullException(nameof(ranges));
            }
            else
            {
                for (int x = 0; x < ranges.Length; x  )
                {
                    if (ranges[x] is null)
                    {
                        throw new ArgumentNullException(nameof(ranges));
                    }
                    else if ((ranges[x].Length > 0 && ranges[x].Length < 2) || ranges[x].Length > 2)
                    {
                        throw new ArgumentException(null);
                    }
                }

                int sum = 0;
                for (int i = 0; i < arrayToSearch.Length; i  )
                {
                    for (int j = 0; j < ranges.Length; j  )
                    {
                        if (ranges[j].Length == 0)
                        {
                            continue;
                        }
                        else if (arrayToSearch[i] >= ranges[j][0] && arrayToSearch[i] <= ranges[j][1])
                        {
                            sum  ;
                        }
                    }
                }

                return sum;
            }
        }

CodePudding user response:

There heaps of ways to do this, one is to use Any

public static int GetDecimalsCount(decimal[] arrayToSearch, decimal[][] ranges)
{
   if (arrayToSearch == null) throw new ArgumentNullException(nameof(arrayToSearch));
   if (ranges == null) throw new ArgumentNullException(nameof(ranges));
   if (ranges.Any(x =>x?.Length != 2)) throw new ArgumentException("Invalid ranges",nameof(ranges));

   return arrayToSearch.Sum(item =>
         ranges.Any(range =>
            item >= range[0] &&
            item <= range[1]) ? 1 : 0);
}

Full Demo Here

You could also can save your self some hassle use a record for the range

Given

public record Range(decimal From, decimal To)
{
   public bool Check(decimal value) => value >= From && value <= To;
}

Example

public static int GetDecimalsCount(decimal[] arrayToSearch, Range[] ranges)
{
   if (arrayToSearch == null) throw new ArgumentNullException(nameof(arrayToSearch));
   if (ranges == null) throw new ArgumentNullException(nameof(ranges));

   return arrayToSearch.Sum(item => ranges.Any(range => range.Check(item)) ? 1 : 0);
}

Usage

var ranges = new Range[]
{
   new( 0.1m, 0.2m ),
   new(0.4m, 0.5m),
   new(decimal.Zero, decimal.One)
};

If you needed to this in loops

public static int GetDecimalsCount(decimal[] arrayToSearch, decimal[][] ranges)
{
   if (arrayToSearch == null) throw new ArgumentNullException(nameof(arrayToSearch));
   if (ranges == null) throw new ArgumentNullException(nameof(ranges));
   if (ranges.Any(x => x?.Length != 2)) throw new ArgumentException("Invalid ranges", nameof(ranges));

   var sum = 0;

   foreach (var item in arrayToSearch)
      foreach (var range in ranges)
         if (item >= range[0] && item <= range[1])
         {
            sum  ;
            break;
         }

   return sum;
}
  • Related