C# quickest way to shift array

前端 未结 20 1200
礼貌的吻别
礼貌的吻别 2020-12-01 01:35

How can I quickly shift all the items in an array one to the left, padding the end with null?

For example, [0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]

Ed

相关标签:
20条回答
  • 2020-12-01 02:35

    You might do it like this:

    var items = new int?[] { 0, 1, 2, 3, 4, 5, 6 };  // Your array
    var itemList = new List<int?>(items);  // Put the items in a List<>
    itemList.RemoveAt(1); // Remove the item at index 1
    itemList.Add(null); // Add a null to the end of the list
    items = itemList.ToArray(); // Turn the list back into an array
    

    Of course, it would be more efficient to get rid of the array entirely and just use a List<>. You could then forget the first line and last line and do it like this:

    var itemList = new List<int?> { 0, 1, 2, 3, 4, 5, 6 };
    itemList.RemoveAt(1); // Remove the item at index 1
    itemList.Add(null); // Add a null to the end of the list
    
    0 讨论(0)
  • 2020-12-01 02:37

    Array copying is an O(n) operation and creates a new array. While array copying can certainly be done quickly and efficiently, the problem you've stated can actually be solved in an entirely different way without (as you've requested) creating a new array/data structure and only creating one small wrapping object instance per array:

    using System;
    using System.Text;
    
    public class ArrayReindexer
    {
        private Array reindexed;
        private int location, offset;
    
        public ArrayReindexer( Array source )
        {
            reindexed = source;
        }
    
        public object this[int index]
        {
            get
            {
                if (offset > 0 && index >= location)
                {
                    int adjustedIndex = index + offset;
                    return adjustedIndex >= reindexed.Length ? "null" : reindexed.GetValue( adjustedIndex );
                }
    
                return reindexed.GetValue( index );
            }
        }
    
        public void Reindex( int position, int shiftAmount )
        {
            location = position;
            offset = shiftAmount;
        }
    
        public override string ToString()
        {
            StringBuilder output = new StringBuilder( "[ " );
            for (int i = 0; i < reindexed.Length; ++i)
            {
                output.Append( this[i] );
                if (i == reindexed.Length - 1)
                {
                    output.Append( " ]" );
                }
                else
                {
                    output.Append( ", " );
                }
            }
    
            return output.ToString();
        }
    }
    

    By wrapping and controlling access to the array in this manner, we can now demonstrate how the problem was solved with an O(1) method call...

    ArrayReindexer original = new ArrayReindexer( SourceArray );
    Console.WriteLine( "   Base array: {0}", original.ToString() );
    ArrayReindexer reindexed = new ArrayReindexer( SourceArray );
    reindexed.Reindex( 1, 1 );
    Console.WriteLine( "Shifted array: {0}", reindexed.ToString() );
    

    Will produce the output:

    Base array: [ 0, 1, 2, 3, 4, 5, 6 ]
    Shifted array: [ 0, 2, 3, 4, 5, 6, null ]

    I'm willing to bet that there will be a reason that such a solution won't work for you, but I believe this does match your initial stated requirements. 8 )

    It's often helpful to think about all the different kinds of solutions to a problem before implementing a specific one, and perhaps that might be the most important thing that this example can demonstrate.

    Hope this helps!

    0 讨论(0)
提交回复
热议问题