如何使用特定字符将数组拆分为较小的数组?

时间:2017-06-20 13:51:10

标签: c# arrays stringbuilder

如何使用特定字符拆分字符串数组?这个例子使用' @':

string [] stringArray = new string [10];
stringArray[0] = "Hi there, this is page one" //goes into new arrayA
stringArray[1] = "Hi there, this is page two" //goes into new arrayA
stringArray[2] = "Hi there, this is page three" //goes into new arrayA
stringArray[3] = "@" //split
stringArray[4] = "New book, page one" //goes into new arrayB
stringArray[5] = "New book, page two" //goes into new arrayB

4 个答案:

答案 0 :(得分:4)

您可以编写一个使用SkipTakeWhile的扩展方法。 此解决方案是通用的,这意味着它可以使用您提供的任何类型。请注意,对于引用类型,将进行值比较,不会进行参考比较。

public static List<List<T>> Split<T>(this List<T> array, T seperator)
{
    var currentIndex = 0;
    var splitedList = new List<List<T>>();
    while (currentIndex < array.Count)
    {
        var part = array.Skip(currentIndex).TakeWhile(item => !item.Equals(seperator)).ToList();
        splitedList.Add(part);
        currentIndex += part.Count + 1;
    }
    return splitedList;
}

string[] stringArray = new string[6];
stringArray[0] = "Hi there, this is page one"; //goes into new arrayA
stringArray[1] = "Hi there, this is page two"; //goes into new arrayA
stringArray[2] = "Hi there, this is page three"; //goes into new arrayA
stringArray[3] = "@"; //split
stringArray[4] = "New book, page one"; //goes into new arrayB
stringArray[5] = "New book, page two"; //goes into new arrayB

var splittedValue = stringArray.ToList().Split("@");

我有一个巨大的列表,你想做一个像分裂的流,你可以使用yield return。它的优点是,当读取列表中的下一个项目时,代码将仅执行到下一个yield return语句。

public static IEnumerable<IList<T>> Split<T>(this IEnumerable<T> collection, T seperator)
{
    var items = new List<T>();
    foreach (var item in collection)
    {
        if (item.Equals(seperator))
        {
            yield return items;
            items = new List<T>();
        }
        else items.Add(item);
    }
    yield return items;
}

答案 1 :(得分:2)

这应该这样做:

public IEnumerable<IEnumerable<T>> Split<T>(IEnumerable<T> input, T splitOn)
{
    var l = new List<T>();
    foreach (var item in input)
    {
        if(object.Equals(item, splitOn))
        {
            yield return l;
            l = new List<T>();
        }
        else
            l.Add(item);
    }
    yield return l;
}

答案 2 :(得分:1)

另一种方法,使用SkipTakeyield return的扩展方法进行延迟加载。在第二次编辑中,我使用泛型来分割所有类型的IEnumerables

public static IEnumerable<IEnumerable<T>> SplitArray<T>(this IEnumerable<T> s,T splitItem)
{
    // First we get all the indexes where the string is found,
    // adding the last index of the array
    var indexes = s.Select((b, i) => b.Equals(splitItem) ? i : -1).Where(i => i != -1)
                   .Union(new int[] { s.Count() }).ToArray();

    int skip = 0; //variable to know where the next chunk starts
    foreach (int index in indexes)
    {
        IEnumerable<T> array = s.Skip(skip).Take(index - skip).ToArray();
        yield return array; //we return the chunk
        skip = index+1;
    }
}

用法:

foreach(var splitted in stringArray.SplitArray("@"))
{
     //splited is a string[]
}

答案 3 :(得分:-2)

如果数组的大小不够大(数千项),您可以加入字符串,然后再将它们拆分:

        string new_string = String.Join("#", stringArray);
        string[] combined_array = new_string.Split("@".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
        string[] new_array_1 = combined_array[0].Split("#".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
        string[] new_array_2 = combined_array[1].Split("#".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

combined_array中的项目数取决于“@”的数量。所以一般来说,你可以遍历combined_array并获得单独的数组。