在数组中添加新字节并移位其余字节

时间:2016-07-27 08:15:58

标签: c#

我的数组看起来像这样

  

17 8B 01 00 03 EA 05 00 14 0A 00 00 03 EA 05 00 14 0A 00 00 00 00 00 FF FF FF FF FF FF FF FF

我想在索引1(8B)之后添加一个额外字节0x00,并将其余字节移到右边。这个数组是32字节长,加上额外的字节(0x00)之后,我希望它保持与32字节相同的长度我不在乎,如果我最后删除FF,因为它的备用字节。所以新数组应该看起来像

  

17 8B 00 01 00 03 EA 05 00 14 0A 00 00 03 EA 05 00 14 0A 00 00 00 00 00 FF FF FF FF FF FF FF。

我怎样才能在c#中做到这一点?

4 个答案:

答案 0 :(得分:5)

如果您在幕后使用Array.Copy(),它将使用非常有效的处理器指令来移动数据:

byte[] array = { 0x17, 0x8B, 0x01, 0x00, 0x03, 0xEA, 0x05, 0x00, 0x14, 0x0A, 0x00, 0x00, 0x03, 0xEA, 0x05, 0x00, 0x14, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

int positionToInsert = 2;
byte valueToInsert = 0;

Array.Copy(array, positionToInsert, array, positionToInsert+1, array.Length-positionToInsert-1);
array[positionToInsert] = valueToInsert;

Array.Copy()专门用于正确处理重叠副本。

答案 1 :(得分:2)

yield return的一些乐趣:

public static IEnumerable<T> InsertAndShift(this T[] array, T value, int index)
{
     //Omitting argument checks: null, range, etc.

     for (int i = 0; i < array.Length - 1; i++)
     {
          if (i < index)
          {
              yield return array[i];
          }
          else if (i == index)
          {
              yield return input;
          }
          else
          {
              yield return array[i - 1];
          }
     }
}

var shiftedArray = array.InsertAndShift(0, 3).ToArray();

我知道它的矫枉过正,但仍然很有趣。 的优势在于它不会改变原始数组。

答案 2 :(得分:2)

您可以执行以下操作:

public static void InsertByte(byte[] array, int index, byte value)
{
    // shifting all bytes one spot. (from back to front)
    for (int i = array.Length - 1; i > index; i--)
        array[i] = array[i - 1];

    // assigning the new value
    array[index] = value;
}

public static byte[] InsertByteInCopy(byte[] array, int index, byte value)
{
    byte[] copy = array.ToArray();
    InsertByte(copy, index, value);
    return copy;
}

更改数组的当前实例更有利于提高性能。

使用Array.Copy将执行以下操作:(未经测试)

public static void InsertByte2(byte[] array, int index, byte value)
{
    Array.Copy(array, index, array, index + 1, a.Length - index - 1);
    array[index] = value;
}

答案 3 :(得分:1)

我在我的实用程序类中有这个:

public static T[] Insert<T>(this T[] array, T val, int position)
{
  Array.Copy(array, position, array, position+1, array.Length-(position+1));
  array[position] = val;        
  return array;
}

您可以在此处查看示例(不作为扩展方法):https://dotnetfiddle.net/vRcIuY

作为扩展方法的用法只是:

array.Insert<byte>(0, 2);

如果可以从第一个参数推断出类型,则不需要通用指定(不是0byte的情况)

请注意,这会改变数组(返回相同的数组只是因为我觉得它很舒服),你可以将它实现为void

更新

我刚刚注意到(这是我的实用程序类中的预期用途),它会返回一个与原始数据长度相同的数组(因此剪切为1)。如果你想返回一个包含1个项目的新数组(在你的问题中你说你不在乎,但为了以防万一),你可以这样做:

public static T[] ArrayInsert<T>(this T[] array, T val, int position)
{
  var ret = new T[array.Length+1];
  if(position != 0)
    Array.Copy(array, 0, ret, 0, position);
  ret[position] = val;
  Array.Copy(array, position, ret, position+1, array.Length-position);          
  return ret;
}

这不会改变原始数组,并返回一个原始长度+ 1的数组,并插入字节。

此处示例:https://dotnetfiddle.net/DpHldh