【问题标题】:C# Splitting An ArrayC# 拆分数组
【发布时间】:2009-12-03 16:48:58
【问题描述】:

我需要在中点将一个大小不确定的数组拆分为两个单独的数组。

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

}

【问题讨论】:

  • 实际上没有大小不定的数组。如果它是一个数组,它有一个 Length 属性。
  • 数组大小由用户输入的变量个数决定。我确实在顶部解释过。

标签: c# arrays


【解决方案1】:

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

【讨论】:

  • 谢谢!第二个是完美的!
  • 这使用了 Linq 序列方法。添加“using System.Linq”命名空间语句。
【解决方案2】:

使用通用拆分方法:

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

【讨论】:

    【解决方案3】:

    我还想添加一个解决方案,将一个数组拆分为几个包含确定数量的单元格的较小数组。

    一个不错的方法是创建一个通用/扩展方法来拆分任何数组。这是我的:

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

    玩得开心:)

    【讨论】:

      【解决方案4】:

      在处理包含大量元素的数组(即字节数组)时,我遇到了 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;
      }
      

      【讨论】:

      • 这是拆分单独列表的最佳方式。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        您为什么将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);
        }
        

        【讨论】:

        • 那只是我在玩代码,它是其中一些以前的东西的残余。
        【解决方案7】:

        我认为您正在寻找的是 Array 类,特别是 Array.Copy 静态方法。如果 C# 数组有方法,您可以认为该类包含将成为数组实例方法的方法。

        【讨论】:

          【解决方案8】:

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

          编辑:给你:

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

          【讨论】:

            【解决方案9】:

            如果功能范式是一个问题,这可能会有所帮助:

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

            【讨论】:

              猜你喜欢
              • 2011-03-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-14
              • 1970-01-01
              • 2021-08-03
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多