Easiest Way to Rotate a List in C#

Easiest way to Rotate a List in c#

You could implement it as a queue. Dequeue and Enqueue the same value.

**I wasn't sure about performance in converting a List to a Queue, but people upvoted my comment, so I'm posting this as an answer.

C#, Rotate a List to the Right by specified places

Here is a approache with Linq with Skip() and Take().

List<int> iList = new List<int>() { 20, 30, 40, 50, 60, 70 };
int rotate = 3;
List<int> lResult = iList.Skip(rotate).Concat(iList.Take(rotate)).ToList();

another approach with a simple loop

int[] items = new int[] { 20, 30, 40, 50, 60, 70 };
int[] result = new int[items.Length];
int rotate = 3;

for (int i = 0; i < items.Length; i++)
{
result[i] = items[(i+rotate)% items.Length];
}

What is the best way to endlessly rotate 3 items in a list in C#

Ideally this would be achieved with a linked list, the advantage is that only node references are disconnected and no internal copying is needed. A C# Queue is actually based a linked list, so this is a fairly appropriate data structure.

However, this can also be done with a List at a small cost. When you do an Insert or Remove, it internally calls Array.Copy and although it's still O(n), providing it doesn't fail a capacity check there is no allocation and is extremely efficient and optimized.

Example Extensions

public static void RotateDown<T>(this IList<T> source)
{
// ideally you would remove first to save a potential capacity expansion
source.Add(source[0]);
source.RemoveAt(0);
}
public static void RotateUp<T>(this IList<T> source)
{
// ideally you would remove first to save a potential capacity expansion
source.Insert(0,source[^1]);
source.RemoveAt(source.Count-1);
}

Test

var list = new List<int>() {1, 2, 3, 4, 5};

Console.WriteLine(string.Join(", ",list));
list.RotateUp();
Console.WriteLine(string.Join(", ", list));
list.RotateUp();
Console.WriteLine(string.Join(", ", list));
list.RotateDown();
Console.WriteLine(string.Join(", ", list));
list.RotateDown();
Console.WriteLine(string.Join(", ", list));

Output

1, 2, 3, 4, 5
5, 1, 2, 3, 4
4, 5, 1, 2, 3
5, 1, 2, 3, 4
1, 2, 3, 4, 5

Note : Methods lack any range checking. Also ideally this would target a less derived interface, though it's only an example.

How to efficiently rotate an array?

This will use less memory in most cases as the second array is only as big as the shift.

public static void Main(string[] args)
{
int[] n = { 1, 2, 3, 4, 5 };
LeftShiftArray(n, 4);
Console.WriteLine(String.Join(",", n));
}

public static void LeftShiftArray<T>(T[] arr, int shift)
{
shift = shift % arr.Length;
T[] buffer = new T[shift];
Array.Copy(arr, buffer, shift);
Array.Copy(arr, shift, arr, 0, arr.Length - shift);
Array.Copy(buffer, 0, arr, arr.Length - shift, shift);
}

How to zip or rotate a variable number of lists?

You can roll your own ZipMany instance which manually iterates each of the enumerations. This will likely perform better on larger sequences than those using GroupBy after projecting each sequence:

public static IEnumerable<TResult> ZipMany<TSource, TResult>(
IEnumerable<IEnumerable<TSource>> source,
Func<IEnumerable<TSource>, TResult> selector)
{
// ToList is necessary to avoid deferred execution
var enumerators = source.Select(seq => seq.GetEnumerator()).ToList();
try
{
while (true)
{
foreach (var e in enumerators)
{
bool b = e.MoveNext();
if (!b) yield break;
}
// Again, ToList (or ToArray) is necessary to avoid deferred execution
yield return selector(enumerators.Select(e => e.Current).ToList());
}
}
finally
{
foreach (var e in enumerators)
e.Dispose();
}
}

How to rotate a list of strings along an axis?

It sounds like you are describing something like this:

private void Form1_Paint(object sender, PaintEventArgs e)
{
foreach (var str in data)
{
e.Graphics.TranslateTransform(str.X, str.Y);
e.Graphics.RotateTransform(30);
e.Graphics.DrawString(str.StringName, mFont, new SolidBrush(Color.Black), new Point(0, 0));
e.Graphics.ResetTransform();
}
}

This snippet first translates, then rotates, draws the string at the transformed origin, and then resets. Both strings are rotated at the same angle on the same X axis, but originate from different points.



Related Topics



Leave a reply



Submit