简体   繁体   English

C#拆分数组

[英]C# Splitting An Array

I need to split an array of indeterminate size, at the midpoint, into two separate arrays. 我需要在中点将一个不确定大小的数组拆分成两个独立的数组。

The array is generated from a list of strings using ToArray(). 使用ToArray()从字符串列表生成数组。

        public void AddToList ()
        {
            bool loop = true;
            string a = "";

            Console.WriteLine("Enter a string value and press enter to add it to the list");
            while (loop == true)
            {
                a = Console.ReadLine();

                if (a != "")
                {
                    mylist.Add(a);
                }
                else
                {
                    loop = false;
                }
            }

        }

        public void ReturnList()
        {
            string x = "";
            foreach (string number in mylist)
            {
                x = x + number + " ";
            }
            Console.WriteLine(x);
            Console.ReadLine();
        }

    }

    class SplitList
    {
        public string[] sTop;
        public string[] sBottom;

        public void Split(ref UList list)  
        {
            string[] s = list.mylist.ToArray();

            //split the array into top and bottom halfs

        }
    }

    static void Main(string[] args)
    {
        UList list = new UList();
        SplitList split = new SplitList();

        list.AddToList();
        list.ReturnList();

        split.Split(ref list);
    }
}

} }

You could use the following method to split an array into 2 separate arrays 您可以使用以下方法将数组拆分为2个单独的数组

public void Split<T>(T[] array, int index, out T[] first, out T[] second) {
  first = array.Take(index).ToArray();
  second = array.Skip(index).ToArray();
}

public void SplitMidPoint<T>(T[] array, out T[] first, out T[] second) {
  Split(array, array.Length / 2, out first, out second);
}

Use a generic split method: 使用通用拆分方法:

public static void Split<T>(T[] source, int index, out T[] first, out T last)
{
    int len2 = source.Length - index;
    first = new T[index];
    last = new T[len2];
    Array.Copy(source, 0, first, 0, index);
    Array.Copy(source, index, last, 0, len2);
}

I also want to add a solution to split an array into several smaller arrays containing a determined number of cells. 我还想添加一个解决方案,将一个数组拆分成几个包含确定数量单元格的较小数组。

A nice way would be to create a generic/extension method to split any array. 一种不错的方法是创建一个通用/扩展方法来拆分任何数组。 This is mine: 这是我的:

/// <summary>
/// Splits an array into several smaller arrays.
/// </summary>
/// <typeparam name="T">The type of the array.</typeparam>
/// <param name="array">The array to split.</param>
/// <param name="size">The size of the smaller arrays.</param>
/// <returns>An array containing smaller arrays.</returns>
public static IEnumerable<IEnumerable<T>> Split<T>(this T[] array, int size)
{
    for (var i = 0; i < (float)array.Length / size; i++)
    {
        yield return array.Skip(i * size).Take(size);
    }
}

Moreover, this solution is deferred. 而且,该解决方案被推迟。 Then, simply call split(size) on your array. 然后,只需在数组上调用split(size)

var array = new byte[] {10, 20, 30, 40, 50};
var splitArray = array.Split(2);

Have fun :) 玩得开心 :)

I had an issue with Linq's Skip() and Take() functions when dealing with arrays with massive amounts of elements (ie byte arrays), where element counts are in the millions. 在处理具有大量元素(即字节数组)的数组时,我遇到了Linq的Skip()和Take()函数的问题,其中元素数量是数百万。

This approach dramatically reduced split execute times for me. 这种方法大大减少了我的分割执行时间。

public static IEnumerable<IEnumerable<T>> Split<T>(this ICollection<T> self, int chunkSize)
{
    var splitList = new List<List<T>>();
    var chunkCount = (int)Math.Ceiling((double)self.Count / (double)chunkSize);

    for(int c = 0; c < chunkCount; c++)
    {
        var skip = c * chunkSize;
        var take = skip + chunkSize;
        var chunk = new List<T>(chunkSize);

        for(int e = skip; e < take && e < self.Count; e++)
        {
            chunk.Add(self.ElementAt(e));
        }

        splitList.Add(chunk);
    }

    return splitList;
}

If you don't have Linq, you can use Array.Copy: 如果您没有Linq,可以使用Array.Copy:

public void Split(ref UList list)
{
    string[] s = list.mylist.ToArray();

    //split the array into top and bottom halfs
    string[] top = new string[s.Length / 2];
    string[] bottom = new string[s.Length - s.Length / 2];
    Array.Copy(s, top, top.Length);
    Array.Copy(s, top.Length, bottom, 0, bottom.Length);

    Console.WriteLine("Top: ");
    foreach (string item in top) Console.WriteLine(item);
    Console.WriteLine("Bottom: ");
    foreach (string item in bottom) Console.WriteLine(item);
}

Why don't you allocate two arrays and copy the contents ? 为什么不分配两个数组并复制内容?

EDIT: here you go: 编辑:你走了:

        String[] origin = new String[4];
        origin[0] = "zero";
        origin[1] = "one";
        origin[2] = "two";
        origin[3] = "three";

        Int32 topSize = origin.Length / 2;
        Int32 bottomSize = origin.Length - topSize;
        String[] sTop = new String[topSize];
        String[] sBottom = new String[bottomSize];
        Array.Copy(origin, sTop, topSize);
        Array.Copy(origin, topSize , sBottom, 0, bottomSize);

Why are you passing the UList as ref? 你为什么把UList作为参考? There doesn't appear to be a need for that. 似乎没有必要。

I would use a generic Split method if I needed to do this: 如果我需要这样做,我会使用通用的Split方法:

public void Split<T>(T[] array, out T[] left, out T[] right)
{
    left = new T[array.Length / 2];
    right = new T[array.Length - left.Length];

    Array.Copy(array, left, left.Length);
    Array.Copy(array, left.Length, right, 0, right.Length);
}

I think what you're looking for is the Array class, specifically the Array.Copy static method. 我认为您正在寻找的是Array类,特别是Array.Copy静态方法。 You can think of that class as containing the methods that would be instance methods of arrays if C# arrays had methods. 如果C#数组有方法,您可以将该类视为包含将成为数组实例方法的方法。

If functional paradigm is a concern, this might help: 如果关注功能范例,这可能会有所帮助:

   public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> seq, Int32 sizeSplits) {
     Int32 numSplits = (seq.Count() / sizeSplits) + 1;
     foreach ( Int32 ns in Enumerable.Range(start: 1, count: numSplits) ) {
        (Int32 start, Int32 end) = GetIndexes(ns);
        yield return seq.Where((_, i) => (start <= i && i <= end));
     }

     (Int32 start, Int32 end) GetIndexes(Int32 numSplit) {
        Int32 indBase1 = numSplit * sizeSplits;
        Int32 start = indBase1 - sizeSplits;
        Int32 end = indBase1 - 1;
        return (start, end);
     }
  }

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

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