Reputation: 12650
If I want to generate an array that goes from 1 to 6 and increments by .01, what is the most efficient way to do this?
What I want is an array, with mins and maxs subject to change later...like this: x[1,1.01,1.02,1.03...]
Upvotes: 8
Views: 17972
Reputation: 1
You could solve it like this. The solution method returns a double array
double[] Solution(double min, int length, double increment)
{
double[] arr = new double[length];
double value = min;
arr[0] = value;
for (int i = 1; i<length; i++)
{
value += increment;
arr[i] = value;
}
return arr;
}
Upvotes: 0
Reputation: 460108
The easiest way is to use Enumerable.Range
:
double[] result = Enumerable.Range(100, 500)
.Select(i => (double)i/100)
.ToArray();
(hence efficient in terms of readability and lines of code)
Upvotes: 12
Reputation: 18780
Use a for loop with 0.01 increments:
List<decimal> myList = new List<decimal>();
for (decimal i = 1; i <= 6; i+=0.01)
{
myList.Add(i);
}
Upvotes: 2
Reputation: 4563
I would just make a simple function.
public IEnumerable<decimal> GetValues(decimal start, decimal end, decimal increment)
{
for (decimal i = start; i <= end; i += increment)
yield return i;
}
Then you can turn that into an array, query it, or do whatever you want with it.
decimal[] result1 = GetValues(1.0m, 6.0m, .01m).ToArray();
List<decimal> result2 = GetValues(1.0m, 6.0m, .01m).ToList();
List<decimal> result3 = GetValues(1.0m, 6.0m, .01m).Where(d => d > 3 && d < 4).ToList();
Upvotes: 5
Reputation: 3892
Assuming a start
, end
and an increment
value, you can abstract this further:
Enumerable
.Repeat(start, (int)((end - start) / increment) + 1)
.Select((tr, ti) => tr + (increment * ti))
.ToList()
Let's break it down:
Enumerable.Repeat
takes a starting number, repeats for a given number of elements, and returns an enumerable (a collection). In this case, we start with the start
element, find the difference between start
and end
and divide it by the increment
(this gives us the number of increments between start
and end
) and add one to include the original number. This should give us the number of elements to use. Just be warned that since the increment
is a decimal/double, there might be rounding errors when you cast to an int.
Select
transforms all elements of an enumerable given a specific selector function. In this case, we're taking the number that was generated and the index, and adding the original number with the index multiplied by the increment.
Finally, the call to ToList
will save the collection into memory.
If you find yourself using this often, then you can create a method to do this for you:
public static List<decimal> RangeIncrement(decimal start, decimal end, decimal increment)
{
return Enumerable
.Repeat(start, (int)((end - start) / increment) + 1)
.Select((tr, ti) => tr + (increment * ti))
.ToList()
}
Edit: Changed to using Repeat, so that non-whole number values will still be maintained. Also, there's no error checking being done here, so you should make sure to check that increment
is not 0 and that start
< end * sign(increment
). The reason for multiplying end by the sign of increment is that if you're incrementing by a negative number, end should be before start.
Upvotes: 17
Reputation: 12102
Whatever you do, don't use a floating point datatype (like double
), they don't work for things like this on behalf of rounding behaviour. Go for either a decimal
, or integers with a factor. For the latter:
Decimal[] decs = new Decimal[500];
for (int i = 0; i < 500; i++){
decs[i] = (new Decimal(i) / 100)+1 ;
}
Upvotes: 0
Reputation: 48568
Elegant
double[] v = Enumerable.Range(1, 600).Select(x => x * 0.01).ToArray();
Efficient
Use for loop
Upvotes: 1
Reputation: 8645
var ia = new float[500]; //guesstimate
var x = 0;
for(float i =1; i <6.01; i+= 0.01){
ia[x] = i;
x++;
}
You could multi-thread this for speed, but it's probably not worth the overhead unless you plan on running this on a really really slow processor.
Upvotes: -1