Срезы строк


В попытке обобщить вопрос и хорошие ответы на этот вопрос, я решил попробовать написать пару строк с расширениями, которые могли бы

  1. разделить строку по отношению к число срезов
  2. разделить строку в отношении количества элементов текста в каждый ломтик.

Эти усилия привели в приведенном ниже коде.

  public static class Extensions
  {

    public static IEnumerable<string> SliceByNumber(this string value, int sliceCount, bool strict = false)
    {
      if (value == null) throw new ArgumentNullException(nameof(value));
      if (sliceCount <= 0) throw new ArgumentException("Number of slices is invalid.", nameof(sliceCount));

      StringInfo stringInfo = new StringInfo(value);
      return stringInfo.Slice(stringInfo.LengthInTextElements / sliceCount, sliceCount, strict);
    }

    public static IEnumerable<string> SliceBySize(this string value, int sliceSize, bool strict = false)
    {
      if (value == null) throw new ArgumentNullException(nameof(value));
      if (sliceSize <= 0) throw new ArgumentException("The size of the slices is invalid.", nameof(sliceSize));

      StringInfo stringInfo = new StringInfo(value);
      return stringInfo.Slice(sliceSize, stringInfo.LengthInTextElements / sliceSize, strict);
    }

    private static IEnumerable<string> Slice(this StringInfo stringInfo, int sliceSize, int sliceCount, bool strict)
    {
      stringInfo.CheckSliceValidity(sliceSize, sliceCount, strict);

      int sliceStart = 0;
      for (; sliceStart < (sliceCount - 1) * sliceSize; sliceStart += sliceSize)
      {
        yield return stringInfo.SubstringByTextElements(sliceStart, sliceSize);
      }

      yield return stringInfo.SubstringByTextElements(sliceStart);
    }

    private static void CheckSliceValidity(this StringInfo stringInfo, int sliceSize, int sliceCount, bool strict)
    {
      if (stringInfo.LengthInTextElements < sliceSize)
        throw new ArgumentOutOfRangeException(nameof(sliceSize), "Number of elements in a slice is greather than the number of characters in the string value.");
      if (stringInfo.LengthInTextElements < sliceCount)
        throw new ArgumentOutOfRangeException(nameof(sliceSize), "Number of slices is greather than the number of characters in the string value.");
      if (strict && sliceSize * sliceCount != stringInfo.LengthInTextElements)
        throw new ArgumentException("Unable to slice the string into a number of strings of equal length.", nameof(sliceSize));

      // Maybe other precautions?
    }
  }

static void SliceTest()
{
  int slicesOrSize= 5;
  string data = "OnceUponATime";

  foreach (string slice in data.SliceByNumber(slicesOrSize, false))
  {
    Console.WriteLine(slice);
  }
  Console.WriteLine();

  foreach (string slice in data.SliceBySize(slicesOrSize, false))
  {
    Console.WriteLine(slice);
  }
}

Какие-либо замечания или улучшения приветствуются.



Комментарии