C# 如何提高数组的索引

C# 如何提高数组的索引,c#,arrays,C#,Arrays,例如,我有一个数组 string[] data = {"1","2","3","5","6","7","4",....goes on) 假设我要执行以下操作;如果数组数据的第三个元素是5,则将所有元素向上移动一个点,基本上数组将变成 {"1","2","3","","5","6","7","4"...} 一个空格将代替5 if (data[3] == "5") { // move index forward one spot } 虽然这可以通过数组来实现,但使用一些更高级的构造(

例如,我有一个数组

string[] data = {"1","2","3","5","6","7","4",....goes on)
假设我要执行以下操作;如果数组数据的第三个元素是
5
,则将所有元素向上移动一个点,基本上数组将变成

{"1","2","3","","5","6","7","4"...}
一个空格将代替5

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

虽然这可以通过数组来实现,但使用一些更高级的构造(如
List
)并在需要时将其转换回数组可能会更容易。如果你根本不需要数组,你可以自己使用
List

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();
string[]数据={“1”、“2”、“3”、“5”、“6”、“7”、“4”};
var列表=新列表(数据);
对于(var i=0;i
这是一个有效的演示:


这是最简单的实现,尽管它不是最有效的——请参阅其他一些关于替代实现的答案,这些替代实现对于大型数据集来说可能是一个更好的选择。

数组的大小是固定的,因此无法将其变大以容纳额外的空白空间

您需要使用<代码>列表<代码>(除非您有理由将这些数字作为字符串处理),并且您将使用函数<代码>清单>索引> <代码>找到“5”和“代码”>列表。
您甚至可能想查看
列表
,因为“空白”可以用null表示。

如其他建议,使用
列表
,但是

// 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();
//presize,因为我们知道
//至少有数据。长度元素!
//从技术上讲,最终阵列将有一个大小

//data.Length类似的方法可能有效:

“此成员是显式接口成员实现。仅当数组实例被强制转换为IList接口时,才能使用它。”

我认为可以将数组强制转换为IList接口。 但是,我无法尝试我的答案。

Linq解决方案:


虽然我相信
列表
答案是最好的,但如果您不想使用列表,这可能是一个更好的解决方案。请注意,数组应该是静态长度

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.
string[]数据={“1”、“2”、“3”、“5”、“6”、“7”、“4”};
var valueToChangeAt=3;
//以上应该是参数,并作为一个单独的方法传递到此中
队列临时持有者=新队列();
对于(变量i=0;i=值更改AT-1)
tempHolder.Enqueue(数据[i]);
}
string[]newData=新字符串[data.Length+1];
对于(var j=0;j

我认为这将是一个合适的解决方案,您不需要创建大量的新对象,您可以将其抽象为一个方法,并使用
Queue
它的使用方式

它必须是数组吗?使用列表会更好在这种情况下,
List
可能会更好,因为它实现了
Insert
您可以使用列表而不是数组吗?我不太喜欢这种解决方案。虽然实现起来很方便,但它复制元素的次数超过了需要的次数。对于像这样小的数据集,这可能不是问题,但庞大的数据集会给您带来麻烦。@NicoSchertler同意,这是最简单的,但不一定是最有效的。我不会修改它,因为大多数更好的选择都包含在其他答案中。我添加了一个注释。如果我们关心效率,我们不应该指定
data.Length+1
的初始容量吗?当然,但我们只关心索引3处的容量。@clcto我解释为“每次看到5移动所有东西”。。。我不认为它是
if(数据[3]=“5”)插入(5,”
  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();
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.