How to increase array index

I have an array like

string[] data = {"1","2","3","5","6","7","4",....goes on)

      

Let's say I want to do the following operation; if the 3rd element of the array data 5

, then move everything up the index one place, basically the array will become

{"1","2","3","","5","6","7","4"...}

      

and the empty space will take 5th place.

if (data[3] == "5") 
{ 
   // move index forward one spot
}

      

+3


source to share


6 answers


While this can be done with an array, it will probably be easier to use some higher level construct, for example List<T>

, and then convert it back to an array if you need to. If you don't need an array, you can just use it List<T>

yourself.

string[] data = {"1","2","3","5","6","7","4"};

var list = new List<string>(data);

for (var i = 0; i < list.Count; i++)
{
    if (list[i] == "5")
    {
        list.Insert(i, "");
        i++;
    }
}

data = list.ToArray();

      



Here's a working demo: https://dotnetfiddle.net/lHzgFH

This is the simplest implementation, although not the most efficient - see some of the other answers for alternative implications that might be better for large datasets.

+7


source


Like others List<>

have suggested , use , BUT ...

// presize, because we know that there are
// at least data.Length elements!
// technically the final array will have a size
// data.Length <= finalSize <= data.Length * 2
var list = new List<string>(data.Length);

for (var i = 0; i < data.Length; i++)
{
    if (data[i] == "5")
    {
        list.Add("");
    }

    list.Add(data[i]);
}

data = list.ToArray();

      

List<>.Insert()

is "slow" because you have to move each element after the inserted element (this is an O (n) operation) ... But the trick is that you can fill List<>

one element at a time, so without using List<>.Insert()

and only withList<>.Add()



Now ... Without creation, List<>

we could calculate the final size of the array, for example:

int count5 = data.Count(x => x == "5");

string[] data2 = new string[data.Length + count5];

for (int i = 0, j = 0; i < data.Length; i++, j++)
{
    if (data[i] == "5")
    {
        data2[j] = "";
        j++;
    }

    data2[j] = data[i];
}

      

+2


source


You cannot do this with an array, since it is a fixed size, so you cannot make it larger to store extra spaces.

You have to use List<int>

(if you have no reason to treat numbers as strings?) And you have to use functions List<int>.IndexOf

to find "5" and List<int>.Insert

- add a space.

You might even want to look List<Nullable<int>>

, since "blank" can be represented by zero.

+1


source


Linq solution (s):

  String[] data = { "1", "2", "3", "5", "6", "7", "4" };

  // put "" before any item if it equals to "5"
  var result = data
    .SelectMany(item => item == "5" ? new String[] {"", item} : new String[] {item})
    .ToArray();

  // put "" before 3d item if it equals to "5" 
  var result2 = data
    .SelectMany((item, index) => (item == "5" && index == 3) ? new String[] {"", item} : new String[] {item})
    .ToArray();

      

+1


source


Something like this might work:

https://msdn.microsoft.com/en-us/library/bb300583%28v=vs.110%29.aspx

"This member is an explicit implementation of an interface member. It can only be used when an Array instance is passed to an IList interface."

I think you can use your array in the IList interface. However, I cannot try my answer.

0


source


While I believe the answer List<T>

is the best, if you don't want to use a list, this might be the best solution. As a side note, arrays must be static length.

string[] data = {"1","2","3","5","6","7","4"};
var valueToChangeAt = 3;
//The above should be parameters, and passed into this as a separate method

Queue<String> tempHolder = new Queue<String>();

for(var i = 0; i < data.Length; i++) {
    if(i >= valueToChangeAt-1)
        tempHolder.Enqueue(data[i]);
}

string[] newData = new string[data.Length+1];

for(var j = 0; j < valueToChangeAt; j++)
    newData[j] = data[j];

newData[valueToChangeAt-1] = "";

for(var k = valueToChangeAt; k < newData.Length; k++)
    newData[k] = tempHolder.Dequeue();

//At this point return newData, allowing your stack and old array to be destroyed.

      

I think this would be the right solution, you are not creating an abundance of new objects, you can divert it to a method and you are using the Queue

way it is intended to be used.

0


source







All Articles