c# - 如何将数组拆分为特定大小的 block ?

标签 c# arrays split

<分区>

下午,

我需要将数组拆分成更小的“ block ”。

我要传递大约 1200 个项目,需要将它们分成更容易处理的数组,每个数组包含 100 个项目,然后我需要处理这些项目。

谁能提出一些建议吗?

最佳答案

Array.Copy 从 1.1 开始就存在,并且在分 block 数组方面做得很好。

string[] buffer;

for(int i = 0; i < source.Length; i+=100)
{
    buffer = new string[100];
    Array.Copy(source, i, buffer, 0, 100);
    // process array
}

并对其进行扩展:

public static class Extensions
{
    public static T[] Slice<T>(this T[] source, int index, int length)
    {       
        T[] slice = new T[length];
        Array.Copy(source, index, slice, 0, length);
        return slice;
    }
}

并使用扩展:

string[] source = new string[] { 1200 items here };

// get the first 100
string[] slice = source.Slice(0, 100);

更新:我想你可能想要 ArraySegment<>不需要进行性能检查,因为它只是使用原始数组作为其源并维护一个 Offset 和 Count 属性来确定“段”。不幸的是,没有办法只将段检索为数组,所以有些人已经为它编写了包装器,如下所示:ArraySegment - Returning the actual segment C#

ArraySegment<string> segment;

for (int i = 0; i < source.Length; i += 100)
{
    segment = new ArraySegment<string>(source, i, 100);

    // and to loop through the segment
    for (int s = segment.Offset; s < segment.Array.Length; s++)
    {
        Console.WriteLine(segment.Array[s]);
    }
}

Array.Copy vs Skip/Take vs LINQ 的性能

测试方法(Release模式下):

static void Main(string[] args)
{
    string[] source = new string[1000000];
    for (int i = 0; i < source.Length; i++)
    {
        source[i] = "string " + i.ToString();
    }

    string[] buffer;

    Console.WriteLine("Starting stop watch");

    Stopwatch sw = new Stopwatch();

    for (int n = 0; n < 5; n++)
    {
        sw.Reset();
        sw.Start();
        for (int i = 0; i < source.Length; i += 100)
        {
            buffer = new string[100];
            Array.Copy(source, i, buffer, 0, 100);
        }

        sw.Stop();
        Console.WriteLine("Array.Copy: " + sw.ElapsedMilliseconds.ToString());

        sw.Reset();
        sw.Start();
        for (int i = 0; i < source.Length; i += 100)
        {
            buffer = new string[100];
            buffer = source.Skip(i).Take(100).ToArray();
        }
        sw.Stop();
        Console.WriteLine("Skip/Take: " + sw.ElapsedMilliseconds.ToString());

        sw.Reset();
        sw.Start();
        String[][] chunks = source                            
            .Select((s, i) => new { Value = s, Index = i })                            
            .GroupBy(x => x.Index / 100)                            
            .Select(grp => grp.Select(x => x.Value).ToArray())                            
            .ToArray();
        sw.Stop();
        Console.WriteLine("LINQ: " + sw.ElapsedMilliseconds.ToString());
    }
    Console.ReadLine();
}

结果(以毫秒为单位):

Array.Copy:    15
Skip/Take:  42464
LINQ:         881

Array.Copy:    21
Skip/Take:  42284
LINQ:         585

Array.Copy:    11
Skip/Take:  43223
LINQ:         760

Array.Copy:     9
Skip/Take:  42842
LINQ:         525

Array.Copy:    24
Skip/Take:  43134
LINQ:         638

关于c# - 如何将数组拆分为特定大小的 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11207526/

相关文章:

python - 如果句子以标点符号结尾,则在不插入无效标记的情况下分割标点符号的有效方法

c# - 如何在运行时更改补间动画的 endValueString?

C# 事件,如何引发它们?

java - 从填充数组计算范围时出现问题(Java)

javascript - 平面数组到深层嵌套对象数组

java 双分割到 String[ ][ ]

Python 将全名拆分为两个变量,姓氏可能包含多个单词

C# MVVM 如何将命令添加到 TextBlock

c# - Facebook C# SDK - 发布到墙上

c - 电位计作为 MSP430g2452 启动板的输入