I have an array for example
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 array data is 5
then move everything up the index one spot, basically the array would then become
{"1","2","3","","5","6","7","4"...}
and a blank space will take 5's place.
if (data[3] == "5")
{
// move index forward one spot
}
While this can be done with an array, it will probably prove easier to use some higher-level construct like List<T>
and then convert this back to an array should you need it. If you don't require an array at all you can just use List<T>
on its own.
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, though it isn't the most efficient - see some of the other answers for alternate implmementations that may prove a better option for large data sets.
As other suggested, use a List<>
, 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();
The List<>.Insert()
is "slow" because you have to move every element after the inserted element (it is a O(n) operation)... But the trick is that you can fill the List<>
one element at a time, so without using List<>.Insert()
and only using List<>.Add()
Now... Without creating a List<>
, we could calculate the final size of the array, like:
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];
}
You can't really do this with an array since it is a fixed size, so you can't make it bigger to hold the extra blanks space.
You need to use List<int>
(unless you have a reason for treating the numbers as strings?), and you would use the functions List<int>.IndexOf
to find the '5', and the List<int>.Insert
to add the blank.
You might even want to look at List<Nullable<int>>
since the 'blank' could be represented by a null.
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();
Something like that could work :
https://msdn.microsoft.com/en-us/library/bb300583%28v=vs.110%29.aspx
"This member is an explicit interface member implementation. It can be used only when the Array instance is cast to an IList interface."
I think you can cast your Array into an IList interface. However, I can't try my answer.
While I believe that the List<T>
answer is the best, if you don't want to use a list this might be a better solution. As a note, Arrays should be a 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 a proper solution, you don't create an abundance of new objects, you are able to abstract it to a method and you use Queue
the way it is meant to be used.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.