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);
}
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;
}