Paging through an IEnumerable - c#

I have an IEnumerable object (IEnumerable<Class>) and I would like to retrieve a specified line from the object. So if I'm on page two I would like to select row two from the IEnumerable object and then pass it on to another class etc.
I'm a bit stuck at the moment, any ideas?

Look at the functions .Take() and .Skip(). I normally do something like this:
IEnumerable<object> GetPage(IEnumerable<object> input, int page, int pagesize)
{
return input.Skip(page*pagesize).Take(pagesize);
}

If I understand your requirements correctly, something like this paging mechanism should work:
int pageSize = 10;
int pageCount = 2;
iEnumerable.Skip(pageSize*pageCount).Take(pageSize);
This example shows 10 rows per page and a page number of 2. So, it will skip to page 2 and take the first row on that page.

Assuming that pages and rows start at 1, and there is a fixed number of rows per page (say 10), you need to transform the page number and the row to an index as follows:
Page 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 ...
Row 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 ...
↓
Index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...
Code:
int page = 2;
int row = 2;
int rowsPerPage = 10;
IEnumerable<MyClass> source = ...
MyClass result = source.ElementAt((page - 1) * rowsPerPage + (row - 1));
So to get row 2 on page 2, you need to skip the first page (10 elements) and then take the second element (index 1 in that page).

I've implemented a dynamic solution in vb.net, i hope helpful:
<Runtime.CompilerServices.Extension()>
Public Function Paginate(Of T As {Class})(source As T, skip As Integer, take As Integer) As T
If source IsNot Nothing AndAlso TypeOf source Is IEnumerable Then
Dim chunk = (From c In DirectCast(source, IEnumerable)).Skip(skip).Take(take).ToList
If chunk.Count = 0 Then Return Nothing
Return AutoMapper.Mapper.Map(chunk, GetType(T), GetType(T))
End If
Return source
End Function

Related

Lookup from a 3-column table and interpolate one of the columns?

I have a table with 3 columns: Temperature, Pressure, and Gain.
interface IEntry
{
public float Temperature {get;}
public int Pressure {get;}
public float Gain {get;}
}
Given a certain "input" pair (Temperature_input, Pressure_input), I would like to match this pair with the ones in the table and lookup the corresponding gains, interpolating in certain cases.
Example:
T P G
3 1 0
3 2 1
3 3 2
3 5 4
6 1 0
6 2 2
6 3 3
8 1 0
8 2 3
9 1 0
Input pair (T = 4, P = 2):
Step 1: As the exact temperature T = 4 is not in the table, the immediate lower and upper temperatures 3 and 6 are examined (8 table entries)
Step 2: The pairs for T = 3, T = 6 are sorted by Pressure (which is an int)
3 1 0
6 1 0
3 2 1
6 2 2
3 3 2
6 3 3
3 5 4
3 5 4
Step 3: Linear interpolation between temperatures of the same pressure:
3 2 1
6 2 2
Result is the interpolated Gain = 1 + (2-1)/(6-3) = 1.33
What is an efficient way of implementing the lookup part of the table, that will be accessed millions of times?

Will not increment according to modulus

I'm trying to increment the number of headers based on the page click by the user. But it seems I cannot get the proper results. (The number of headers should also increment.)
I just want to have 1 header only on page 2, 2 headers in page 3, and so on.
Trying to get a result like this :
Clicked page : 1 2 3 4 5 6 7 8 9 10 11
no of headers: 1 1 2 3 4 5 5 6 7 8 9
Here is my code :
var page = 3; //example only
var api = page;
if (page % 5 != 2)
{
api -= 1;
}
else
{
api++;
}
What am I doing wrong?

Creating all possible arrays without nested for loops [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I would like to generate all the possible numbers that have length n and each digit of my number has a value from the set {1,2,...,n-1}, as an array. In other words, I would like to list all the base n numbers with length n that do not include 0.
Right now, the only way I can think to do it is by nesting n for loops, and assigning myArray[i] with the (i+1)th loop, i.e.
int n;
int[] myArray = new int[n];
for (int i1 = 1; i1 < n; i1++)
myArray[0]=i1;
for (int i2 = 1; i2 < n; i2++)
myArray[1]=i2;
// and so on....
for (int in = 1; in < n; in++)
{
myArray[n]=in;
foreach (var item in myArray)
Console.Write(item.ToString());
Console.Write(Environment.NewLine);
}
and then printing each array at the innermost loop. The obvious issue is that for each n, I need to manually write n for loops.
From what I've read, recursion seems to be the best way to replace nested for loops, but I can't seem figure out how to make a general method for recursion either.
EDIT
For example, if n=3, I would like to write out 1 1 1, 1 1 2, 1 2 1, 1 2 2, 2 1 1, 2 1 2, 2 2 1, 2 2 2.
We are not limited to n<11. For example, if n=11, we would output
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 1 1 3
...
1 1 1 1 1 1 1 1 1 1 10
1 1 1 1 1 1 1 1 1 2 1
1 1 1 1 1 1 1 1 1 2 2
1 1 1 1 1 1 1 1 1 2 3
...
1 1 1 1 1 1 1 1 1 9 10
1 1 1 1 1 1 1 1 1 10 1
1 1 1 1 1 1 1 1 1 10 2
1 1 1 1 1 1 1 1 1 10 3
...
10 10 10 10 10 10 10 10 10 9 10
10 10 10 10 10 10 10 10 10 10 1
10 10 10 10 10 10 10 10 10 10 2
...
10 10 10 10 10 10 10 10 10 10 10
So, a digit of a number may be any value between and including 1 and 10. The array myArray is simply used to get one of these numbers, then we print it, and go on to the next number and repeat.
As always, when thinking in recursive solutions, try to solve the problem using immutable structures; everything is much simpler to understand.
So first of all, lets build ourselves a fast little immutable stack that will help us keep track of the number we are currently generating (while not worrying about what other numbers are being generated in the recursive call...remember, immutable data can't change!):
public class ImmutableStack<T>: IEnumerable<T>
{
public static readonly ImmutableStack<T> Empty = new ImmutableStack<T>();
private readonly T first;
private readonly ImmutableStack<T> rest;
public int Count { get; }
private ImmutableStack()
{
Count = 0;
}
private ImmutableStack(T first, ImmutableStack<T> rest)
{
Debug.Assert(rest != null);
this.first = first;
this.rest = rest;
Count = rest.Count + 1;
}
public IEnumerator<T> GetEnumerator()
{
var current = this;
while (current != Empty)
{
yield return current.first;
current = current.rest;
}
}
public T Peek()
{
if (this == Empty)
throw new InvalidOperationException("Can not peek an empty stack.");
return first;
}
public ImmutableStack<T> Pop()
{
if (this == Empty)
throw new InvalidOperationException("Can not pop an empty stack.");
return rest;
}
public ImmutableStack<T> Push(T item) => new ImmutableStack<T>(item, this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
That's easy. Note how the stack reuses data. How many empty immutable structs will there be in our little program? Only one. And stacks containing the sequence 1->2->4? Yup, only one.
Now, we implement a recursive function that just keeps adding numbers to the stack until we reach our "bail out" condition. Which is? When the stack contains n elements. Easy peasy:
private static IEnumerable<int> generateNumbers(ImmutableStack<string> digits, IEnumerable<string> set, int length)
{
if (digits.Count == length)
{
yield return int.Parse(string.Concat(digits));
}
else
{
foreach (var digit in set)
{
var newDigits = digits.Push(digit);
foreach (var newNumber in generateNumbers(newDigits, set, length))
{
yield return newNumber;
}
}
}
}
Ok, and now we just need to tie it alltogether with our public method:
public static IEnumerable<int> GenerateNumbers(int length)
{
if (length < 1)
throw new ArgumentOutOfRangeException(nameof(length));
return generateNumbers(ImmutableStack<string>.Empty,
Enumerable.Range(1, length - 1).Select(d => d.ToString(CultureInfo.InvariantCulture)),
length);
}
And sure enough, if we call this thing:
var ns = GenerateNumbers(3);
Console.WriteLine(string.Join(Environment.NewLine,
ns.Select((n, index) => $"[{index + 1}]\t: {n}")));
We get the expected output:
[1] : 111
[2] : 211
[3] : 121
[4] : 221
[5] : 112
[6] : 212
[7] : 122
[8] : 222
Do note that the total amount of numbers generated of a specified length n is (n - 1) ^ n which means that for relatively small values of length you are going to get quite an amount of numbers generated; n = 10 generates 3 486 784 401...

C#'s Random producing recognisable pattern when using sequential seeds

Given the following:
for(int seed = 0; seed < 100; seed++) {
var random = new Random(seed);
var roll = (random.Next() % 6) + 1;
Console.Write(roll + " ");
}
I'm seeing a clear pattern in the output:
1 1 2 2 3 3 4 4 5 5 6 6 1 1 1 2 2 3 3 4 4 5 5 6 6
1 1 2 2 3 3 4 4 5 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6
1 1 2 2 3 3 4 4 4 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6
1 1 2 2 3 3 3 4 4 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6
I do understand that recreating a new Random object every time with a sequential seed isn't the "proper" way of using the class, and that strictly speaking I should be keep the Random instance around, calling Next() on it each time.
However, my use case is that I need to be able to exit my program and restore the state at any moment, and continue the sequence of numbers.
I also need the user to be able to set a seed manually, so I was hoping to be able to do something like:
var random = new Random(userSeed + nextValueIndex);
var chosenValue = random.Next();
I've also tried random.Next(min, max), and it gives different results, but also in a clear pattern.
Clearly my approach isn't the right way to use the Random class, but what is, for my use case?
I understand that random number generation is a very complex topic, so while I'm sort of interested in an explanation of why this is happening, I'm most interested in a practical (easy?) solution ;-)
Here's my solution, which seems to work nicely. Rather than seeding Random with userSeed + index (where index counts from zero), I simply cache the exact result from Random as previousRandom, and then seed with userSeed + previousRandom. That way, I get nice big numbers as the seed, and it avoids the sequential pattern. (previousRandom is initialised as zero, but that's not a problem.)
So, this is roughly what my code looks like:
var nextSeed = userSeed + this.previousRandom;
var randomObj = new Random(nextSeed);
var nextRandomValue = randomObj.Next ();
var chosenValue = (nextRandomValue % randomRange) + rangeMin;
this.previousRandom = nextRandomValue;
return chosenValue;
The one remaining thing I should probably do is make sure that userSeed + previousRandom doesn't overflow (or overflows predictably), because previousRandom might get very close to int's upper bound (up to whatever range I allow for userSeed).

permutations of k objects from a set of n algorithm

I'm looking for an efficient way to achieve this:
you have a set of numbers, let's say that our set is equal to 4 (N = 4);
you have to generate all permutations of 3 elements (K = 3);
Output for N = 4 and K = 3:
1 2 3
1 2 4
1 3 2
1 3 4
1 4 2
1 4 3
2 1 3
2 1 4
2 3 1
2 3 4
2 4 1
2 4 3
3 1 2
3 1 4
3 2 1
3 2 4
3 4 1
3 4 2
4 1 2
4 1 3
4 2 1
4 2 3
4 3 1
4 3 2
Anyone have a great, nice'n'quick algorithm up their sleeve or web reference??
Thanks!
Something like this pseudocode:
permute(set, output, len) //output will hold all the permutations
for each number in the set do
choose number and store it at output[0]
if(!empty(set))
call permute(set{without the number}, output + (len - 1)!, len-1) //adjust the position
Invoke by permute(set, output, k)

Categories

Resources