Calculating maximum and minimum values in an array - c#

I have an array of integers and need to find the position in the array of the maximum number along with the minimum. I have it working but it doesn't seem to be a very good way to do it. Can anyone suggest a better way to achieve what I have?
Here's my code:
int[] usageHours = { 3, 3, 5, 4, 0, 0, 2, 2, 4, 25, 158, 320, 212, 356, 401, 460, 480, 403, 298, 213, 102, 87, 34, 45 };
double myAverage = usageHours.Average();
int runningTotal = 0;
int runningMaxPosition = 0;
for (int i = 0; i < usageHours.Length; i++)
{
if (usageHours[i] > runningTotal)
{
runningMaxPosition = i;
runningTotal = usageHours[i];
}
}
txtmax.Text = Convert.ToString(runningMaxPosition)+" With: "+Convert.ToString(runningTotal)+" Users";
txtAv.Text = Convert.ToString(myAverage);

That code is mostly fine. I'd suggest changing the variable names a bit, but that's all. You can work out the minimum in the same loop. I've changed the "if" conditions very slightly to guarantee that they always pick out at least one element (even if all the values are, say, int.MinValue). There are other ways of approaching this, but this is one example. If you have an empty array, you'll end up with max=min=0, and both indexes=-1.
int currentMax = 0;
int currentMaxIndex = -1;
int currentMin = 0;
int currentMinIndex = -1;
for (int i = 0; i < usageHours.Length; i++)
{
if (currentMaxIndex == -1 || usageHours[i] > currentMax)
{
currentMaxIndex = i;
currentMax = usageHours[i];
}
if (currentMinIndex == -1 || usageHours[i] < currentMin)
{
currentMinIndex = i;
currentMin = usageHours[i];
}
}
Here's an alternative using nullable value types to represent "there were no values" answers:
int currentMax? = null;
int currentMaxIndex? = null;
int currentMin? = null;
int currentMinIndex? = null;
for (int i = 0; i < usageHours.Length; i++)
{
if (currentMax == null || usageHours[i] > currentMax.Value)
{
currentMax = i;
currentMax = usageHours[i];
}
if (currentMin == null || usageHours[i] < currentMin.Value)
{
currentMinIndex = i;
currentMin = usageHours[i];
}
}
Don't worry if you haven't come across nullable value types yet though...

The code looks OK for finding the max value. If you are using C# 3 or later you could use the LINQ extension methods (there are Min, Max and Average methods, and on List there is also a FindIndex method, amongst others), but I get the impression that you are learning programming, and then it is sometimes a good idea to implement stuff that may be built into the framework, just for the learning value.

I just wanted to provide one-liner solution for the question (for completeness).
In the OP's original question he only asks for index of the maximum and index of the minimum.
Let's stick to this question. This is the most interesting question because to find maximum value we can simply use Enumerable.Max LINQ method. The same goes for Min and Average.
Let's only provide index of the max, index of min can be retrieved with similar code.
int indexOfMax = Enumerable.Range(0, usageHours.Length).Aggregate(
(indexOfMax, i) => (usageHours[i] > usageHours[indexOfMax] ? i : indexOfMax)
);
Delegate inside of Aggregate's brackets is executed for each index of array. It gets as parameters "index of maximum value so far found", and current index. It returns "index of maximum value so far found". Obviously in each iteration "index of maximum value so far found" will only change to current index if corresponding element of array is greater than previous maximum.

scratch the linq code, it didnt work the way you wanted
you could make your code a little bit more concise
for (int i = 0; i < usageHours.Length; i++)
{
if (usageHours[i] > usageHours[runningMaxPosition])
runningMaxPosition = i;
}
all it does differently is leavs out the temporary runningTotal variable.

How about this:
double average = usageHours.Average();
int maxPosition = Enumerable.Range(0, usageHours.Length).Max(i => usageHours[i]);
int minPosition = Enumerable.Range(0, usageHours.Length).Min(i => usageHours[i]);

Your code isn't bad, but it won't work if all the values are less than zero.
Try this:
int getArrayMaxPosition (double[] theArray)
{
double maxVal = theArray[0];
int ret = 0;
int currentIndex = 0;
foreach (double aValue in theArray)
{
if (aValue > maxVal)
{
ret = currentIndex;
maxVal = avalue;
}
currentIndex++;
}
return ret;
}

As was mentioned on the comment's to Jon's answer, Jon's solution really is the best, most direct, quickest way of doing it.
If, however, you did want to use Igor's solution, here's the rest of it (to get the actual positions as well as the values):
int maxValue = Enumerable.Range(0, usageHours.Length).Max(i => usageHours[i]);
int maxPosition = Array.FindIndex(usageHours, i => i == maxValue);
int minValue = Enumerable.Range(0, usageHours.Length).Min(i => usageHours[i]);
int minPosition = Array.FindIndex(usageHours, i => i == minValue);

Related

How do I add up Double Values from multiple String Arrays at the same position? C#

I get Strings like this from my database:
NaN#Nan#44.20216139610997#45.35340149990988#45.44329482112824#45.1593428796393#NaN#NaN
values = SQLvalues.Split('#'); //produces Array you can see in the picture
(String[] values)
Going on further with strings until it ends with about 10 "NaN" Strings again.
What I am doing now is that I sum up all the values from that one Array.
But there will be about 100 more Arrays after this one and I need to add up for example values[8] from this Array with the one at the same position from the next Array.
hope this visualizes better what I need to do
As I am still an apprentice I don´t have much knowledge on all of this.
I´ve been trying to come with a solution for several hours now but I won´t seem to get anything to work here.
Any help would be great!
My Code:
String[] values;
String returnString = "";
List<Double> valueList = new List<Double>();
DateTime time = (DateTime)skzAdapterText.MinTambourChangedTime();
DataTable profilData = skzAdapterText.LoadValuesText(time);
int rowCount = profilData.Rows.Count;
for (int i = 0; i < rowCount; i++)
{
String SQLvalues = (String)profilData.Rows[i][2];
values = SQLvalues.Split('#');
double summe = 0;
int counter = 0;
foreach (String tmpRow in values)
{
Double value;
if (double.TryParse(tmpRow, NumberStyles.Float | NumberStyles.AllowThousands,
CultureInfo.InvariantCulture, out value)
&& !double.IsNaN(value))
{
counter++;
summe = summe + value;
}
}
if (summe != 0 && counter != 0)
valueList.Add(summe / counter);
}
The basic sum can be reduced like so:
values = SQLvalues.Split('#');
double sum = values.Where(v => v != "NaN").Select(v => double.Parse(v)).Sum();
For a specific position, say index 8, within many rows:
//Read the data from DB
DataTable profilData = skzAdapterText.LoadValuesText(time);
//parse out the values
var rowValueArrays = // will be a List<double[]>
profilData.Rows.
Select(r => r[2].Split('#').Select(v => v == "NaN"?0.0:double.Parse(v)).ToArray()).
ToList();
// sum the entries at index 8
double sumAt8 = rowValueArrays.Select(r => r[8]).Sum();
You say you are an apprentice, and so the syntax here may be unfamiliar to you and seem difficult to understand. But I want to emphasize the power here. The combination of IEnumerable, lambda expressions, and linq operations reduced the original sample down to two lines of code, and solved the full problem in what is technically three lines (spread out a little for readability). If I wanted to sacrifice any sense of style or maintainability, we could do it in just one line of code.
In short, it is well worth your time to learn how to write code this way. With practice, reading and writing code this way can become easy and greatly increase your speed and capability as a programmer.
I also see attempts to compute an average. Continuing from the end of the previous code:
int countAt8 = rowValuesArrays.Count(r => r[8] != 0.0);
double average = sumAt8 / countAt8;
Finally, I need to point out delimited data like this in a column is an abuse of the database and very poor practice. Schemas like this are considered broken, and need to be fixed.
As you want to sum up the values at the same positions of the arrays, I assume that all these array have the same length. Then first declare the required arrays. You also must probably calculate the average for each array position, so you also need an array for the counter and the averages.
double[] average = null;
int rowCount = profilData.Rows.Count;
if (rowCount > 0) {
string[] values = ((string)profilData.Rows[0][2]).Split('#');
int n = values.Length;
double[] sum = new double[n];
double[] counter = new double[n];
for (int i = 0; i < rowCount; i++) {
values = ((string)profilData.Rows[i][2]).Split('#');
for (int j = 0; j < n; j++) {
if (double.TryParse(values[j], NumberStyles.Float | NumberStyles.AllowThousands,
CultureInfo.InvariantCulture, out double value) && !double.IsNaN(value)) {
counter[j]++;
sum[j] += value;
}
}
}
average = new double[n];
for (int i = 0; i < n; i++) {
if (counter[i] != 0) {
average[i] = sum[i] / counter[i];
}
}
}
You cannot calculate the average while summing up, since you must divide the total sum by the total count. Therefore, I added another loop calculating the averages at each array position after the summing phase.

Split int into chunks with a max value

I've been trying to do the following, I have a max value and a int, I want to split that int like this:
Max = 10
Int = 45
Result = [10, 10, 10, 10, 5]
I already search a lot and I didn't find nothing like the thing I want to do, and my head hurts for thinking and trying to do it.
Thank you for any help!
You just need to repeat the max the number of times it divides into your value. Then if it does not divide evenly add the remainder.
int value = 45;
int max = 10;
var results = Enumerable.Repeat(max, value/max).ToList();
if(value % max != 0)
results.Add(value % max);
Console.WriteLine(string.Join(",", results));
I think LINQ is the nicest way to do this, but you could also have a straightforward loop approach that finds how many times the size fits into your max value, then add these numbers to a List<int>, and add the leftover(if any) to the list at the end.
var size = 10;
var max = 45;
// Find how many times the size fits and leftover
var goesInto = max / size;
var leftover = max % size;
var result = new List<int>();
// Add the sizes that fit in first
for (var i = 0; i < goesInto; i++)
{
result.Add(size);
}
// Add leftover size at the end.
if (leftover > 0)
{
result.Add(leftover);
}
That looks a lot like Pseudo code. We however will write C# code, as that was the langauge tag.
//Need a list, or have to calculate the expected lenght. List is easier.
List<int> ResultList = new List<int>();
//Make a copy to work with
int temp = value;
//Now let us math down towards 0
while(temp>0){
//All those multiples of Max are added first
if(temp >= Max){
ResultList.Add(Max);
temp -= Max;
}
//We are down to the rest, here
else{
//If the rest is not 0, you can add it too
if(temp > 0){
ResultList.Add(temp);
temp = 0;
}
}
}
Here how you do in plain code without LINQ, List, etc. This will also take care of negatives
int val = -45; // negative
int max = 10;
int count = Math.Abs(val / max);
int rem = Math.Abs(val % max);
var output = new int[count + (rem == 0 ? 0 : 1)];
for(int i = 0; i < output.Length ; i++)
{
if (i == output.Length - 1)
output[i] = rem;
else
output[i] = max;
Console.WriteLine(output[i]);
}
return output;
10
10
10
10
5

Quick Sort Implementation with large numbers [duplicate]

I learnt about quick sort and how it can be implemented in both Recursive and Iterative method.
In Iterative method:
Push the range (0...n) into the stack
Partition the given array with a pivot
Pop the top element.
Push the partitions (index range) onto a stack if the range has more than one element
Do the above 3 steps, till the stack is empty
And the recursive version is the normal one defined in wiki.
I learnt that recursive algorithms are always slower than their iterative counterpart.
So, Which method is preferred in terms of time complexity (memory is not a concern)?
Which one is fast enough to use in Programming contest?
Is c++ STL sort() using a recursive approach?
In terms of (asymptotic) time complexity - they are both the same.
"Recursive is slower then iterative" - the rational behind this statement is because of the overhead of the recursive stack (saving and restoring the environment between calls).
However -these are constant number of ops, while not changing the number of "iterations".
Both recursive and iterative quicksort are O(nlogn) average case and O(n^2) worst case.
EDIT:
just for the fun of it I ran a benchmark with the (java) code attached to the post , and then I ran wilcoxon statistic test, to check what is the probability that the running times are indeed distinct
The results may be conclusive (P_VALUE=2.6e-34, https://en.wikipedia.org/wiki/P-value. Remember that the P_VALUE is P(T >= t | H) where T is the test statistic and H is the null hypothesis). But the answer is not what you expected.
The average of the iterative solution was 408.86 ms while of recursive was 236.81 ms
(Note - I used Integer and not int as argument to recursiveQsort() - otherwise the recursive would have achieved much better, because it doesn't have to box a lot of integers, which is also time consuming - I did it because the iterative solution has no choice but doing so.
Thus - your assumption is not true, the recursive solution is faster (for my machine and java for the very least) than the iterative one with P_VALUE=2.6e-34.
public static void recursiveQsort(int[] arr,Integer start, Integer end) {
if (end - start < 2) return; //stop clause
int p = start + ((end-start)/2);
p = partition(arr,p,start,end);
recursiveQsort(arr, start, p);
recursiveQsort(arr, p+1, end);
}
public static void iterativeQsort(int[] arr) {
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
stack.push(arr.length);
while (!stack.isEmpty()) {
int end = stack.pop();
int start = stack.pop();
if (end - start < 2) continue;
int p = start + ((end-start)/2);
p = partition(arr,p,start,end);
stack.push(p+1);
stack.push(end);
stack.push(start);
stack.push(p);
}
}
private static int partition(int[] arr, int p, int start, int end) {
int l = start;
int h = end - 2;
int piv = arr[p];
swap(arr,p,end-1);
while (l < h) {
if (arr[l] < piv) {
l++;
} else if (arr[h] >= piv) {
h--;
} else {
swap(arr,l,h);
}
}
int idx = h;
if (arr[h] < piv) idx++;
swap(arr,end-1,idx);
return idx;
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String... args) throws Exception {
Random r = new Random(1);
int SIZE = 1000000;
int N = 100;
int[] arr = new int[SIZE];
int[] millisRecursive = new int[N];
int[] millisIterative = new int[N];
for (int t = 0; t < N; t++) {
for (int i = 0; i < SIZE; i++) {
arr[i] = r.nextInt(SIZE);
}
int[] tempArr = Arrays.copyOf(arr, arr.length);
long start = System.currentTimeMillis();
iterativeQsort(tempArr);
millisIterative[t] = (int)(System.currentTimeMillis()-start);
tempArr = Arrays.copyOf(arr, arr.length);
start = System.currentTimeMillis();
recursvieQsort(tempArr,0,arr.length);
millisRecursive[t] = (int)(System.currentTimeMillis()-start);
}
int sum = 0;
for (int x : millisRecursive) {
System.out.println(x);
sum += x;
}
System.out.println("end of recursive. AVG = " + ((double)sum)/millisRecursive.length);
sum = 0;
for (int x : millisIterative) {
System.out.println(x);
sum += x;
}
System.out.println("end of iterative. AVG = " + ((double)sum)/millisIterative.length);
}
Recursion is NOT always slower than iteration. Quicksort is perfect example of it. The only way to do this in iterate way is create stack structure. So in other way do the same that the compiler do if we use recursion, and propably you will do this worse than compiler. Also there will be more jumps if you don't use recursion (to pop and push values to stack).
That's the solution i came up with in Javascript. I think it works.
const myArr = [33, 103, 3, 726, 200, 984, 198, 764, 9]
document.write('initial order :', JSON.stringify(myArr), '<br><br>')
qs_iter(myArr)
document.write('_Final order :', JSON.stringify(myArr))
function qs_iter(items) {
if (!items || items.length <= 1) {
return items
}
var stack = []
var low = 0
var high = items.length - 1
stack.push([low, high])
while (stack.length) {
var range = stack.pop()
low = range[0]
high = range[1]
if (low < high) {
var pivot = Math.floor((low + high) / 2)
stack.push([low, pivot])
stack.push([pivot + 1, high])
while (low < high) {
while (low < pivot && items[low] <= items[pivot]) low++
while (high > pivot && items[high] > items[pivot]) high--
if (low < high) {
var tmp = items[low]
items[low] = items[high]
items[high] = tmp
}
}
}
}
return items
}
Let me know if you found a mistake :)
Mister Jojo UPDATE :
this code just mixes values that can in rare cases lead to a sort, in other words never.
For those who have a doubt, I put it in snippet.

How to use LINQ with a 2 dimensional array

I have a 2-dimensional byte array that looks something like this:
0 0 0 0 1
1 1 1 1 0
0 0 1 1 1
1 0 1 0 1
Each value in the array can only be 0 or 1. The above simplified example shows 4 rows with each row having 5 columns. I am trying to figure out how to use LINQ to return the index to the row that has the largest number of 1s set, which in the above example should return 1.
The following non LINQ C# code solves the problem:
static int GetMaxIndex(byte[,] TwoDArray)
{
// This method finds the row with the greatest number of 1s set.
//
int NumRows = TwoDArray.GetLength(0);
int NumCols = TwoDArray.GetLength(1);
int RowCount, MaxRowCount = 0, MaxRowIndex = 0;
//
for (int LoopR = 0; LoopR < NumRows; LoopR++)
{
RowCount = 0;
for (int LoopC = 0; LoopC < NumCols; LoopC++)
{
if (TwoDArray[LoopR, LoopC] != 0)
RowCount++;
}
if (RowCount > MaxRowCount)
{
MaxRowCount = RowCount;
MaxRowIndex = LoopR;
}
}
return MaxRowIndex;
}
static void Main()
{
byte[,] Array2D = new byte[4, 5] { { 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 0 }, { 0, 0, 1, 1, 1 }, { 1, 0, 1, 0, 1 } };
int MaxInd = GetMaxIndex(Array2D);
Console.WriteLine("MaxInd = {0}", MaxInd);
}
So, my questions are:
How can LINQ be used to solve this, and would using LINQ here be less efficient that using the non LINQ code above?
Is it possible to solve this problem with PLINQ? Or, would it be more efficient to use the Task Parallel Library (TPL) directly for the above code and split out the count of the number of 1s in each row to a separate thread, assuming that each row has at least 1,000 columns?
It's hard to work with multidimentional arrays with LINQ, but here's how you could do:
var arr = new [,] { { 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 0 }, { 0, 0, 1, 1, 1 }, { 1, 0, 1, 0, 1 } };
var data =
Enumerable.Range(0, 4)
.Select(
row =>
new
{
index = row,
count = Enumerable.Range(0, 5).Select(col => arr[row, col]).Count(x => x == 1)
})
.OrderByDescending(x => x.count)
.Select(x => x.index)
.First();
Here is how I would do it. It's the same as others more or less, but without any Enumerable.Range (not that there is anything wrong with those (I use them all the time)...it just makes the code more indented in this case).
This one also includes PLINQ stuff. TPL (async/await) wouldn't be suitable for this because it is computationally bound and TPL is better suited to I/O bound operations. Your code would end up executing sequentially if you used async/await rather than PLINQ. This is because async/await won't go parallel until the thread is released (and it can start the next task...which could then go parallel) and purely synchronous functions (such as CPU stuff) won't every actually await...they'll just run all the way through. Basically, it would finish the first thing in your list before it even started the next thing, making it sequentially executed. PLINQ explicitly starts parallel tasks and doesn't have this issue.
//arry is your 2d byte array (byte[,] arry)
var maxIndex = arry
.Cast<byte>() //cast the entire array into bytes
.AsParallel() //make the transition to PLINQ (remove this to not use it)
.Select((b, i) => new // create indexes
{
value = b,
index = i
})
.GroupBy(g => g.index / arry.GetLength(1)) // group it by rows
.Select((g, i) => new
{
sum = g.Select(g2 => (int)g2.value).Sum(), //sum each row
index = i
})
.OrderByDescending(g => g.sum) //max by sum
.Select(g => g.index) //grab the index
.First(); //this should be the highest index
In terms of efficiency, you would probably get better results with your for loop. The question I would ask is, which is more readable and clear?
1) You can do it with LINQ this way...
private static int GetMaxIndex(byte[,] TwoDArray) {
return Enumerable.Range(0, TwoDArray.GetLength(0))
.Select(
x => new {
Index = x,
Count = Enumerable.Range(0, TwoDArray.GetLength(1)).Count(y => TwoDArray[x, y] == 1)
})
.OrderByDescending(x => x.Count)
.First()
.Index;
}
... you'd have to test it to see if LINQ is faster or slower.
2) It is possible to use PLINQ. Just use ParallelEnumerable.Range for the row index generator
private static int GetMaxIndex2(byte[,] TwoDArray) {
return ParallelEnumerable.Range(0, TwoDArray.GetLength(0))
.Select(
x => new {
Index = x,
Count = Enumerable.Range(0, TwoDArray.GetLength(1)).Count(y => TwoDArray[x, y] == 1)
})
.OrderByDescending(x => x.Count)
.First()
.Index;
}
Looking at the issue, this is really a two part answer for whatever is "more efficient" for your code. The loop presented is already very lean on resources, but could be more clear on the intent.
Based on the size of data being moved around, even at 10x that, PLINQ is going to be more resource intensive, just because of how much work it is to spin up a thread.
1.) Using LINQ can make this method more readable
Most 2d array LINQ queries I've come across convert it into a jagged array (or array of arrays) before searching. Here's a helper method that does that conversion for us, and to help make this guy look cleaner:
public static T[][] GetJagged<T>(this T[,] raw)
{
int lenX = raw.GetLength(0);
int lenY = raw.GetLength(1);
T[][] jagged = new T[lenX][];
for (int x = 0; x < lenX; x++)
{
jagged[x] = new T[lenY];
for (int y = 0; y < lenY; y++)
{
jagged[x][y] = raw[x, y];
}
}
return jagged;
}
Now, all we have left is to query the now 1d array for each member, and return the sum of each member. Here, I use the selector (b => b), essentially saying if there's a byte, select if for the Sum method.
static int GetMaxIndexLINQ(byte[,] TwoDArray)
{
byte[][] jagged = TwoDArray.GetJagged();
IEnumerable<int> rowSums = from bitRows in jagged
select bitRows.Sum((b) => b);
int maxIndex = rowSums.Max();
int MaxRowIndex = Array.IndexOf(rowSums.ToArray(), maxIndex);
return MaxRowIndex;
}
This way comes out very legible and even if the reader is new to coding, it's pretty easy to get the gist of what's happening here.
I'd like to point out that making your code more readable is making it more efficient. Teamwork makes the dream work, and the quicker a teammate can clearly make sense of what is happening in your code, the better for everyone.
2.) Optimizing for performance
As I said before, there isn't a lot happening here that can be made any leaner, any method calls or unnecessary checking will just slow this process down.
That being said, there is a small change to be made for some easy optimization. Because in this instance we are only dealing with 1s and 0s, there is a real benefit where we can use the internal optimizations the compiler makes, to our benefit. Rather than checking if a value is 0 or not, it is actually much faster to just add it in to our running sum!
static int GetMaxIndex_EvenBetter(byte[,] TwoDArray)
{
int NumRows = TwoDArray.GetLength(0);
int NumCols = TwoDArray.GetLength(1);
int RowCount, MaxRowCount = 0, MaxRowIndex = 0;
for (int row = 0; row < NumRows; row++)
{
RowCount = 0;
for (int col = 0; col < NumCols; col++)
{
RowCount += TwoDArray[row, col]; //See my change here
}
if (RowCount > MaxRowCount)
{
MaxRowCount = RowCount;
MaxRowIndex = row;
}
}
return MaxRowIndex;
}
In most other cases you aren't working with just the 1s and 0s, so you DO want to check those values before adding, here however, unnecessary.
// This code is extracted from
// http://www.codeproject.com/Articles/170662/Using-LINQ-and-Extension-Methods-in-C-to-Sort-Vect
private static IEnumerable<T[]> ConvertToSingleDimension<T>(T[,] source)
{
T[] arRow;
for (int row = 0; row < source.GetLength(0); ++row)
{
arRow = new T[source.GetLength(1)];
for (int col = 0; col < source.GetLength(1); ++col)
arRow[col] = source[row, col];
yield return arRow;
}
}
// Convert byte[,] to anonymous type {int index, IEnumerable<byte[]>} for linq operation
var result = (from item in ConvertToSingleDimension(Array2D).Select((i, index) => new {Values = i, Index = index})
orderby item.Values.Sum(i => i) descending, item.Index
select item.Index).FirstOrDefault();

How to keep the latest X elements of a list

I need to use a data structure that would keep the latest X elements of a list. A colleague gave me this solution:
int start = 0;
const int latestElementsToKeep = 20;
int[] numbers = new int[latestElementsToKeep];
for (int i = 0; i < 30; i++)
{
numbers[start] = i;
if (start < numbers.Length - 1)
{
start++;
}
else
{
start = 0;
}
}
So after this is run, the numbers array has numbers 19-29 (the latest 20 numbers).
That's nice, but difficult to use this in the real world. Is there an easier way to do this?
This seems like a pretty standard Circular Buffer. My only suggestion would be to create a class for it or download one of the libraries available. There seem to be a few promising looking ones near the top of the Google results.
Easier way to do this:
int[] numbers = new int[latestElementsToKeep];
for (int i = 0; i < 30; i++)
numbers[i % latestElementsToKeep] = i;
Modulus operator returns the reminder of dividing i by latestElementsToKeep. When i reaches latestElementsToKeep, you will start from the beginning.
For a range of numbers, you can use:
int keep = 20;
int lastItem = 29;
int[] numbers = Enumerable.Range(lastItem - keep, keep).ToArray();
To get the last items from any collection (where you can get the size), you can use:
int keep = 20;
someType[] items = someCollection.Skip(someCollection.Count() - keep).ToArray();

Categories