如何增加数组的索引

本文关键字:数组 索引 增加 何增加 | 更新日期: 2023-09-27 18:00:27

我有一个数组,例如

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<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

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

按照其他人的建议,使用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()是"慢"的,因为你必须在插入的元素之后移动每个元素(这是一个O(n)运算)。。。但诀窍是,你可以一次填充一个元素的List<>,所以不使用List<>.Insert(),只使用List<>.Add()

现在。。。在不创建List<>的情况下,我们可以计算阵列的最终大小,如:

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];
}

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();

由于数组是固定大小的,因此您无法真正对其执行此操作,因此无法将其变大以容纳多余的空格。

您需要使用List<int>(除非您有理由将数字视为字符串?),然后使用函数List<int>.IndexOf查找"5",并使用List<int>.Insert添加空白。

您甚至可能想要查看List<Nullable<int>>,因为"blank"可以用null表示。

类似的东西可以工作:

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

"此成员是显式接口成员实现。只有当Array实例强制转换为IList接口时,才能使用它。"

我认为您可以将Array强制转换为IList接口。然而,我无法尝试我的答案。

虽然我认为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