【问题标题】:C# Split array into fixed number of rangesC#将数组拆分为固定数量的范围
【发布时间】:2013-07-17 21:06:41
【问题描述】:

我有一个任意长度的 byte[] 数组,我想将其拆分为多个部分,每个部分的长度为 2205,我必须对这 2205 个字节进行操作,这是我的算法:

// SPLIT BY 2205 Bytes
int block = 2205;
int counter = 0;
byte[] to_Send = new byte[block];
foreach (byte b in ARCHIEVE_BUFFER)
{
    if (counter < 2205)
    {
        to_Send[counter] = b;
        counter++;
    }
    else if (counter == 2205)
    {
        // do some operation on those 2205 bytes which stored on the array to_send

        counter = 0;
        to_Send[counter] = b;
        counter++;
    }
}

我只想将数组拆分为固定数量的范围

【问题讨论】:

  • 你的问题是什么?
  • 您可能需要查看Array.Copy
  • 您的问题是什么?我认为你的措辞令人困惑。问题标题听起来像是您想要固定数量的子集,但问题主体听起来像是您想要子集的固定大小,并且尽可能多。..

标签: c# .net arrays buffer


【解决方案1】:

使用 linq,您可以将数组拆分为 blocksize 字节块

int count=0;
int blocksize = 2205;
List<List<byte>> blocks =  ARCHIEVE_BUFFER
                            .GroupBy( _ => count++ / blocksize)
                            .Select(x=>x.ToList())
                            .ToList();

【讨论】:

  • 有趣的代码,但你认为它会高效吗? (在这里并不重要,只是想知道)
【解决方案2】:

类 Array 有一个静态方法,可以从一个数组复制到另一个数组,从两个数组中的一个位置开始,并达到指定的长度

Array.Copy(array1, pos1, array2, pos2, length)

int block = 2205;
int counter = 0;
byte[] to_Send = new byte[block];
Array.Copy(ARCHIEVE_BUFFER, 0, to_Send, 0, 2205);

不清楚你想用第一个块填充to_Send 数组做什么,但是应该很容易在 Array.Copy 周围添加一个循环,在每个循环处更改起始位置并使用新的从 ARCHIEVE_BUFFER 中提取的数据

【讨论】:

    【解决方案3】:

    创建一个新数组并为此使用 Buffer.BlockCopy。 遍历一个数组并为每个字节复制一个字节是非常低效的。

    byte[] toSend = null;
    int Remaining = ARCHIEVE_BUFFER.Length;
    int Packed = 0;
    
    while(Remaining > 0){
       toSend = new byte[Remaining >= block ? block : Remaining];
       Buffer.BlockCopy(toSend, 0, ARCHIEVE_BUFFER, Packed, toSend.Length); // not sure about params
       Packed += toSend.Length;
       Remaining -= toSend.Length;
    
       // todo: send here
    }
    

    【讨论】:

    • 您可以使用 Math.Min 代替三元。
    • 将是一种易于阅读的方式!我经常使用三元(也在 JavaScript 中),因为它认为这比在堆栈(或者可能是堆或寄存器中)上移动数据更快 - 取决于参数传递给机器的方式。我不确定 Math.Min 是如何在 IL 中翻译的 - 也许它只是简化为三进制。
    • 这是我见过的最小的优化。只需使用 Math.Min。
    【解决方案4】:

    如上所述,使用Array.Copy 方法或Buffer.BlockCopy。但是,在性能关键的情况下,请使用BlockCopy

    Array.Copy(sourceArray, 0, destinationArray, 0, size);
    

    Buffer.BlockCopy(sourceArray, 0, destinationArray, 0, size);
    

    【讨论】:

      【解决方案5】:

      或者另一种方式,使用Enumerable.SkipEnumerable.Take

      //ARCHIEVE_BUFFER: source array 
      //block: the size of slice
      for(var i=0; i<ARCHIEVE_BUFFER.Length;i+=block) {
          var to_Send = ARCHIEVE_BUFFER.Skip(i).Take(block);
          ProcessSubArray(to_Send);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-06
        • 1970-01-01
        相关资源
        最近更新 更多