我有一个例如
的数组string[] data = {"1","2","3","5","6","7","4",....goes on)
假设我想做以下操作;如果数组数据的第3个元素是5
,那么将索引上的所有内容移动一个点,基本上数组就会变为
{"1","2","3","","5","6","7","4"...}
并且空格将占据5位。
if (data[3] == "5")
{
// move index forward one spot
}
答案 0 :(得分:7)
虽然可以使用数组完成,但可能更容易使用某些更高级别的构造,如List<T>
,然后在需要时将其转换回数组。如果您根本不需要阵列,则可以单独使用List<T>
。
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();
这是一个有效的演示:https://dotnetfiddle.net/lHzgFH
这是最简单的实现,虽然它不是最有效的 - 请参阅其他一些可能证明是大数据集更好选择的替代实施的其他答案。
答案 1 :(得分:2)
正如其他建议的那样,使用List<>
,但是......
// 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()
是&#34;慢&#34;因为你必须在插入的元素之后移动每个元素(它是一个O(n)操作)......但是诀窍是你可以一次填充List<>
一个元素,所以不使用{{1并且仅使用List<>.Insert()
现在......在不创建List<>.Add()
的情况下,我们可以计算出数组的最终大小,例如:
List<>
答案 2 :(得分:1)
你不能用数组做到这一点,因为它是一个固定的大小,所以你不能把它做得更大,以保持额外的空白空间。
您需要使用List<int>
(除非您有理由将数字视为字符串?),您可以使用List<int>.IndexOf
函数找到&#39; 5&#39;,和List<int>.Insert
添加空白。
您甚至可能希望查看List<Nullable<int>>
,因为空白&#39;可以用null表示。
答案 3 :(得分:1)
Linq 解决方案:
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();
答案 4 :(得分:0)
这样的事情可以起作用:
https://msdn.microsoft.com/en-us/library/bb300583%28v=vs.110%29.aspx
&#34;该成员是显式接口成员实现。它只能在将Array实例强制转换为IList接口时使用。&#34;
我认为您可以将Array转换为IList接口。 但是,我无法回答。
答案 5 :(得分:0)
虽然我认为List<T>
答案是最好的,但如果您不想使用列表,这可能是更好的解决方案。作为一个注释,数组应该是一个静态长度。
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.
我认为这是一个合适的解决方案,你不会创建大量的新对象,你可以将它抽象为一个方法,并按照它的使用方式使用Queue
。