-6

文字列の配列をn 個の個別の配列に分割するメソッドを書きたいと思います。それぞれの配列は、指定したおおよそのサイズです。

たとえば、分割したい配列に 23 要素がある場合、要素のおおよその数として 7 を指定すると、次のようになります。

1st array with 8 elements
2nd array with 8 elements 
3rd array with 7 elements

別の例として、100 個の要素があり、配列ごとに 18 個の要素を指定すると、次のようになります。

1st array 20 
2nd array 20
3rd array 20
4th array 20
5th array 20

これまでのところ、関数が文字列配列のリストを返す必要があることはわかっていますが、それ以降はどうすればよいかわかりません。

private List<string[]> divStrings(int ExpectedStringsPerArray, 
    string[] AllStrings)
{
    // ...
}

配列の数は

 Math.Floor(AllStrings.Count()/ExpectedStringsPerArray) 

C#で配列を個別の配列に分割するにはどうすればよいですか?

4

4 に答える 4

4

これは簡単すぎるように思われるため、おそらくあなたの質問を間違って解釈します。

  1. ソース配列を分割する配列の数を決定します。( totalCount / elementsPerArray )
  2. 各配列について:
    1. そこに入れる要素の数を決定します。( ElementsRemaining / arraysRemaining )
    2. それらの要素を新しい配列にコピーします。

コード内:

private static List<string[]> DivideStrings(int expectedStringsPerArray, string[] allStrings)
{
    List<string[]> arrays = new List<string[]>();

    int arrayCount = allStrings.Length / expectedStringsPerArray;

    int elemsRemaining = allStrings.Length;
    for (int arrsRemaining = arrayCount; arrsRemaining >= 1; arrsRemaining--)
    {
        int elementCount = elemsRemaining / arrsRemaining;

        string[] array = CopyPart(allStrings, elemsRemaining - elementCount, elementCount);
        arrays.Insert(0, array);

        elemsRemaining -= elementCount;
    }

    return arrays;
}

 

private static T[] CopyPart<T>(T[] array, int index, int length)
{
    T[] newArray = new T[length];
    Array.Copy(array, index, newArray, 0, length);
    return newArray;
}

このように使用すると:

const int count = 23;
const int estimate = 7;
string[] strings = Enumerable.Range(1, count).Select(s => s.ToString()).ToArray();
var list = DivideStrings(estimate, strings);
foreach (var arr in list)
    Console.WriteLine(String.Join(" ", arr));

それは印刷します:

1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23
于 2013-03-20T03:07:39.937 に答える
3

を使用Enumerable.Rangeして分割数を取得し、 および を使用して項目をLinq Skip選択Takeして配列を選択できます。

例:

 public List<string[]> divStrings(int count, string[] array)
 {
    long remainder;
    long divCount = Math.DivRem(array.Count(), count, out remainder);
    int ajustedCount = (int)((divCount > remainder) 
                       ? (divCount / remainder) 
                       : (remainder / divCount)) + count;
    int groupCount = (ajustedCount * divCount) > array.Count() 
        ? (int)divCount
        : (int)divCount++;
    return Enumerable.Range(0, groupCount).Select(g => array.Skip(g * ajustedCount).Take(ajustedCount).ToArray()).ToList();
 }

でも

これは便利な拡張メソッドになる可能性があります

public static class Extensions
{
    public static List<T[]> SplitEven<T>(this T[] array, int count)
    {
        long remainder;
        long divCount = Math.DivRem(array.Count(), count, out remainder);
        int ajustedCount = (int)((divCount > remainder) 
                           ? (divCount / remainder) 
                           : (remainder / divCount)) + count;
        int groupCount = (ajustedCount * divCount) > array.Count() 
            ? (int)divCount
            : (int)divCount++;
        return Enumerable.Range(0, groupCount).Select(g => array.Skip(g * ajustedCount).Take(ajustedCount).ToArray()).ToList();
    }   
}

使用法:

string[] test = new string[]{};
var result = test.Split<string>(7);

int[] test = new int[]{};
var result = test.Split<int>(7);
于 2013-03-20T03:02:04.323 に答える
2

どうぞ。.ToArray()を使用してリストを配列に変更したり、.ToList() を使用して配列をリストに変更したりできることを覚えておいてください。

List<List<string>> divStrings(int ExpectedStringsPerArray, List<string> AllStrings)
{
    //Set what we're currently up to in the array
    var espa = ExpectedStringsPerArray;
    var ListOfLists = new List<List<string>>();

    //Add the first bunch of elements to the list of lists.
    ListOfLists.Add(AllStrings.Take(ExpectedStringsPerArray).ToList());

    //While we still have elements left to get out
    while (AllStrings.Skip(espa).Take(ExpectedStringsPerArray).Count() != 0)
    {
        //Add the list data we're currently up to to the list of lists
        ListOfLists.Add(AllStrings.Skip(espa).Take(ExpectedStringsPerArray).ToList());
        //Offset what we're up to so next time we're getting the next lot of data
        espa += ExpectedStringsPerArray;
    }

    return ListOfLists;
}

これを次のように呼び出します。

divStrings(30,testList);

于 2013-03-20T02:37:31.027 に答える
1

この質問は答えられています。私はこれに出くわし、私のやり方で答えました。

近似とはどういう意味かわかりませんが、それはすべきではないと思います。探している配列のサイズを確認する必要があります。以下は、テストされていないコード サンプルです。

List<List<int>> lists = new List<List<int>>();
const int myLimit = 20;

var numbers = (from n in myArray select n).ToList();

while (numbers.Any())
{
    var list = (from number in numbers select number).Take(myLimit).ToList();
    numbers.RemoveRange(0, list.Count());
    lists.Add(list);
}

// Now lists should have list of equal number if items in each. Last one may be an exception.

それが役に立てば幸い。

于 2013-07-11T11:18:37.303 に答える