How to transfer the beginning of an array to C #?

I am trying to reorganize an array based on the first occurrence of a value (thus imitating similar functionality to a circular array.)

For example, in the following array, I want the first occurrence of the value 6 to become the new first element, and the previous elements to become the last:

So:

int[] myArray = {2, 3, 6, 1, 7, 6};

It becomes:

myArray = {6, 1, 7, 6, 2, 3};

What is the best way to achieve this?

+5
source share
8 answers
int[] myArray = { 2, 3, 6, 1, 7, 6 };
myArray = myArray
            .SkipWhile(i => i != 6)
            .Concat(myArray.TakeWhile(i => i != 6))
            .ToArray();

Do the trick!

You will need to use System.Linq;

+19
source

Thorsten's solution creates a new array; here in place of the version that only creates a temporary array the size of your rotation size:

public static void RotateLeft<T>(T[] array, int places)
{
    T[] temp = new T[places];
    Array.Copy(array, 0, temp, 0, places);
    Array.Copy(array, places, array, 0, array.Length - places);
    Array.Copy(temp, 0, array, array.Length - places, places);
}

, , :)

" ":

public static void RotateLeft<T>(T[] array)
{
    T temp = array[0];
    Array.Copy(array, 0, array, 1, array.Length - 1);
    array[array.Length-1] = temp;
}
+9

:

  • ,
  • " "
  • Array.Copy(),
  • Array.Copy(), 0, .

, , .

Array.Copy(), , .

+5

, , :

// value contains the value to find.

int skip;
for (int i = 0; i < array.Length; i++)
{
    if (array[i] == value)
    {
        skip = i;
        break;
    }
}

// skip contains the index of the element to put at the front.
// Equivalently, it is the number of items to skip.
// (I chose this name for it because it makes the subtractions
// in the Array.Copy implementation more intuitive.)

? , :

int[] array = new int[] { 2, 3, 6, 1, 7, 6 };
int[] result = new int[array.Length];

int skip = 2; // So that array[skip] will be result[0] at the end

Array.Copy(array, skip, result, 0, array.Length - skip);
Array.Copy(array, 0, result, array.Length - skip, skip);

, ? :

array[(i + skip) % array.Length]  // Instead of array[i]

: - Jon Skeet (sourceValue):

// GCD gives the greatest common divisor
int gcd = GCD(array.Length, skip);

// period is the length of the permutation cycles in our rotation.
int period = array.Length / gcd;

int max = array.Length / period;
for (int i = 0; i < max; i++)
{
    int sourceIndex = i;
    int sourceValue = array[sourceIndex];

    for (int n = 1; n <= period; n++)
    {
        int destinationIndex = (sourceIndex + array.Length - skip) % array.Length;

        int temp = array[destinationIndex];
        array[destinationIndex] = sourceValue;
        sourceValue = temp;

        sourceIndex = destinationIndex;
    }
}
+5

:

class CircularList<T> : IList<T>
{
    static IEnumerable<T> ToEnumerator(CircularList<T> list)
    {
        for (int i = 0; i < list.Count; i++)
        {
            yield return list[i];
        }
    }

    IList<T> arr;
    public int Shift { get; private set; }
    public CircularList(IList<T> arr, int shift)
    {
        this.arr = arr;
        this.Shift = shift;
    }

    int shiftIndex(int baseIndex)
    {
        return (baseIndex + Shift) % arr.Count;
    }

    #region IList<T> Members

    public int IndexOf(T item) { throw new NotImplementedException(); }
    public void Insert(int index, T item) { throw new NotImplementedException(); }
    public void RemoveAt(int index) { throw new NotImplementedException(); }
    public T this[int index]
    {
        get { return arr[shiftIndex(index)]; }
        set { arr[shiftIndex(index)] = value; }
    }

    #endregion

    #region ICollection<T> Members

    public void Add(T item) { throw new NotImplementedException(); }
    public void Clear() { throw new NotImplementedException(); }
    public bool Contains(T item) { throw new NotImplementedException(); }
    public void CopyTo(T[] array, int arrayIndex) { throw new NotImplementedException(); }
    public int Count { get { return arr.Count; } }
    public bool IsReadOnly { get { throw new NotImplementedException(); } }
    public bool Remove(T item) { throw new NotImplementedException(); }

    #endregion

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        return ToEnumerator(this).GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return ToEnumerator(this).GetEnumerator();
    }

    #endregion
}

:

class Program
{
    static void Main(string[] args)
    {
        int[] myArray = { 2, 3, 6, 1, 7, 6 };
        CircularList<int> circularList =
            new CircularList<int>(myArray, Array.IndexOf<int>(myArray, 6));

        foreach (int i in circularList)
        {
            Console.WriteLine(i);
        }
    }
}

:

6
1
7
6
2
3
+3
var ar = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
ar = ar.SkipWhile(a => a != 6).ToArray<int>();
0

# : : {1, 2, 3, 5, 6, 7, 8}; : {8, 7 1, 2, 3, 5, 6};

{
    static void Main(string[] args)
    {
        int[] array = { 1, 2, 3, 5, 6, 7, 8 };
        int index = 2;
        int[] tempArray = new int[array.Length];
        array.CopyTo(tempArray, 0);

        for (int i = 0; i < array.Length - index; i++)
        {
            array[index + i] = tempArray[i];
        }

        for (int i = 0; i < index; i++)
        {
            array[i] = tempArray[array.Length -1 - i];
        }            


    }
}
0
source

A new approach that will only work with .NET 4.5 (from 2012) or later:

  const int value = 6;
  int[] myArray = { 2, 3, 6, 1, 7, 6, };

  var index = Array.IndexOf(myArray, value);
  if (index == -1)
    throw new InvalidOperationException();

  var rotatedArray = (new ArraySegment<int>(myArray, index, myArray.Length - index))
    .Concat(new ArraySegment<int>(myArray, 0, index))
    .ToArray();

In earlier versions of .NET, the value ArraySegment<>could not be used as IEnumerable<>.


It’s not clear to me whether this requirement was for the original instance of the array to be mutated, but if you need it, just add:

  rotatedArray.CopyTo(myArray, 0);

into my code.

0
source

All Articles