【问题标题】:Splitting an array into 2 arrays C#将一个数组拆分为 2 个数组 C#
【发布时间】:2012-05-28 20:31:46
【问题描述】:

编辑:我尝试了 Take/Skip 方法,但出现以下错误:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<string>' to   
'string[]'. An explicit conversion exists (are you missing a cast?)

我不知道自己做错了什么,因为我复制了 Saeed 的代码。

我有一个字符串数组(包含 20 到 300 个项目),我想将它分成 2 个单独的数组,从第一个数组的中间开始。

我知道如何使用 for 循环来做到这一点,但我想知道是否有更快/更好的方法来做到这一点。我还需要能够正确拆分数组,即使它有奇数个项目,例如:

string[] words = {"apple", "orange", "banana", "pear", "lemon"};
string[] firstarray, secondarray;
SplitArray(words, out firstarray, out secondarray); // Or some other function
// firstarray has the first 3 of the items from words, 'apple', 'orange' and 'banana'
// secondarray has the other 2, 'pear' and 'lemon'

【问题讨论】:

  • 为了解决你的演员问题,在 Take 和 skip 方法之后添加 .ToArray()

标签: c# arrays linq


【解决方案1】:

你可以使用 linq:

firstArray = array.Take(array.Length / 2).ToArray();
secondArray = array.Skip(array.Length / 2).ToArray();

尽管原始数组大小是奇偶校验的,为什么这仍然有效?

第一个数组接受array.Length / 2元素,第二个跳过第一个array.Length / 2元素,这意味着这两个数组之间没有任何冲突。当然,如果元素的数量是奇数,我们不能将数组分成大小相等的两个部分。

如果您想在前半部分有更多元素(在奇数情况下),请执行以下操作:

firstArray = array.Take((array.Length + 1) / 2).ToArray();
secondArray = array.Skip((array.Length + 1) / 2).ToArray();

【讨论】:

  • 谢谢,我会尽快尝试,但是即使它有奇数个项目,它是否能正确处理拆分?
  • @Saaed:它不符合规定的要求。给定示例数据,firstArray 将包含{"apple","orange"}secondArray 将包含{"banana","pear","lemon"}。 Matthew 表示第一个数组应该是两个数组中较长的一个;这是否真的是一个问题取决于他!
  • @LukeH,谢谢,我没有读过他的cmets,我根据你的笔记更新了答案。 (我也是 Saeed,不是 Saaed :)
  • @LukeH 哪个数组(firstarray 或 secondarray)有额外的一项并不重要,但感谢您的评论!
  • @saeed +1 4 成为我的朋友和同事 + 有用的答案 ;)
【解决方案2】:
string[] words = {"apple", "orange", "banana", "pear", "lemon"};
int mid = words.Length/2;
string[] first = words.Take(mid).ToArray();
string[] second = words.Skip(mid).ToArray();

【讨论】:

  • 谢谢!我很快就会试试这个。
【解决方案3】:

如果您不想/不能使用 LINQ,您可以这样做:

    string[] words = { "apple", "orange", "banana", "pear", "lemon" };
    string[] firstarray, secondarray;
    int mid = words.Length / 2;
    firstarray = new string[mid];
    secondarray = new string[words.Length - mid];
    Array.Copy(words, 0, firstarray, 0, mid);
    Array.Copy(words, mid, secondarray, 0, secondarray.Length);

【讨论】:

    【解决方案4】:

    一种更通用的方法,可以将其拆分为您指定的多个部分:

    public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> list, int parts)
            {
              return list.Select((item, index) => new {index, item})
                           .GroupBy(x => (x.index + 1) / (list.Count()/parts) + 1)
                           .Select(x => x.Select(y => y.item));
            }
    

    *已编辑感谢 skarmats

    【讨论】:

    • 这将改变事物的顺序。所以第 n 个结果数组将不对应于源的第 n 部分。
    • 已更新以防止对数组进行条带化。
    【解决方案5】:
    string[] words = { "apple", "orange", "banana", "pear", "lemon" };
    var halfWay = words.Length/2;
    
    var firstHalf = words.Take(halfWay);
    var secondHalf = words.Skip(halfWay);
    

    【讨论】:

      【解决方案6】:

      您可以使用范围表示法轻松实现:

      var x = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
      var pivot = x.Length / 2;
      var p1 = x[..pivot];
      var p2 = x[pivot..];
      

      【讨论】:

        【解决方案7】:

        以防万一有人想使用函数:

            static void Main(string[] args)
            {
                string[] ar = { "apple", "orange", "banana", "pear", "lemon" };
        
                int half =  ar.Length / 2;
        
                //  Console.WriteLine(string.Join(',', Split(ar,0, half)));
        
                Console.WriteLine(string.Join(',', Split(ar,half, ar.Length)));
        
                Console.ReadKey();
            }
        
        
            public static IEnumerable<T> Split<T>(IEnumerable<T> items, int start, int end)
            {
                return items.Skip(start).Take(end);
            }
        

        【讨论】:

        • 您采用了易于理解的 SkipTake 运算符并将它们替换为不易理解的 SplitArray 函数,该函数仅限于处理数组(相对于 IEnumerable&lt;T&gt; ) 并且你引入了 startend 参数,它们没有明确的含义。
        • 非常感谢您的评论。我实际上花时间测试它,它适用于字符串和整数,我猜它适用于其他类型。现在,开始和结束,我不得不不同意开始和结束很难理解。基本上,您想拆分一个数组,但是您想从哪里开始拆分以及在哪里结束。这就是为什么我认为这很容易理解。感谢您的评论,如果您对我提到的内容有任何疑虑或评论,我希望向您学习。 :)
        • 更新了函数,使其与 IEnumerable 一起工作,而不仅仅是数组。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-11
        • 2021-12-18
        • 1970-01-01
        • 2012-01-01
        相关资源
        最近更新 更多