简体   繁体   English

如何增加数组的索引

[英]How to increase index of array

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 如果数组数据的第3个元素是5那么将所有内容向上移动索引一个点,基本上数组就会变为

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

and a blank space will take 5's place. 一个空白区域将占据5位。

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. 虽然可以使用数组来完成,但可能更容易使用像List<T>这样的更高级别的构造,然后在需要时将其转换回数组。 If you don't require an array at all you can just use List<T> on its own. 如果您根本不需要数组,则可以单独使用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();

Here's a working demo: https://dotnetfiddle.net/lHzgFH 这是一个有效的演示: 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... 正如其他建议的那样,使用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();

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() List<>.Insert()是“慢”因为你必须在插入的元素之后移动每个元素(它是一个O(n)操作)...但是技巧是你可以填充List<>一个元素一次,所以不使用List<>.Insert()并仅使用List<>.Add()

Now... Without creating a List<> , we could calculate the final size of the array, like: 现在......在不创建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];
}

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. 您需要使用List<int> (除非您有理由将数字视为字符串?),您将使用函数List<int>.IndexOf查找'5'和List<int>.Insert添加空白。

You might even want to look at List<Nullable<int>> since the 'blank' could be represented by a null. 您甚至可能希望查看List<Nullable<int>>因为'blank'可以用null表示。

Linq solution(s): 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();

Something like that could work : 这样的东西可以工作:

https://msdn.microsoft.com/en-us/library/bb300583%28v=vs.110%29.aspx 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." “此成员是显式接口成员实现。只有在将Array实例强制转换为IList接口时才能使用它。”

I think you can cast your Array into an IList interface. 我认为你可以将你的数组转换为IList接口。 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. 虽然我认为List<T>答案是最好的,但如果您不想使用列表,这可能是更好的解决方案。 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. 我认为这是一个合适的解决方案,你不会创建大量的新对象,你可以将它抽象为一个方法,并按照它的使用方式使用Queue

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM