C#数组分割

39

我需要将一个大小不确定的数组,在中点处分成两个独立的数组。

该数组是使用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);
    }
}

}


3
其实并不存在大小不确定的数组。如果是数组,它就有一个 Length 属性。 - Joel Mueller
1
数组大小根据用户输入的变量数量确定。我在顶部进行了解释。 - TheValheruGod
9个回答

70
您可以使用以下方法将一个数组拆分为两个单独的数组。
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);
}

谢谢!第二个完美无缺! - TheValheruGod
2
这里使用了 Linq 序列方法。请添加 "using System.Linq" 命名空间语句。 - CJBS

13
我希望您能够将一个数组拆分为几个包含确定数量元素的较小数组,涉及到IT技术方面的内容。以下是我的示例代码,可以创建一个通用/扩展方法来拆分任何数组。请参考以下内容:

示例代码:

/// <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);
    }
}

此外,这个解决方案是延后的。然后,只需在数组上调用 split(size) 即可。
var array = new byte[] {10, 20, 30, 40, 50};
var splitArray = array.Split(2);

玩得开心 :)


12

使用通用的分割方法:

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);
}

9

当处理具有大量元素(例如字节数组)且元素计数在百万级别的数组时,我在使用Linq的Skip()和Take()函数时遇到了问题。

采用这种方法极大地减少了我的拆分执行时间。

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;
}

1
这是分割独立列表的最佳方法。 - SPARTAN

1

如果您没有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);
}

0

为什么不分配两个数组并复制内容呢?

编辑:这是你要的:

        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);

0

为什么你要将 UList 作为引用传递?貌似没有必要这样做。

如果我需要这样做,我会使用一个通用的 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);
}

那只是我对代码的玩耍,它是之前某些存在的东西的遗留物。 - TheValheruGod

0
我认为你要找的是Array类,特别是Array.Copy静态方法。你可以把这个类想象成包含了如果C#数组有方法的实例方法的类。

0
如果函数式编程是一个问题,这可能会有所帮助:
   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);
     }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接