Как строку 256 символов разбить на 8 блоков и поместить в массив uint?
Имеется строка 256 символов
ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
Как ее разбить на 8 блоков и поместить в массив uint[]?
Ответы (1 шт):
Например, так:
Enumerable.Range(0, s.Length / 8)
.Select(n => uint.Parse(s.AsSpan(n * 8, 8),
NumberStyles.HexNumber,
CultureInfo.InvariantCulture))
.ToArray();
Объяснение:
Мы делим строку на блоки по 8 символов, всего таких блоков будет s.Length / 8. Enumerable.Range(0, s.Length / 8) выдаёт последовательность индексов от 0 do максимального.
Далее, для каждого индекса мы берём нужный блок. Для индекса n он начинается с позиции n * 8, т. к. длина каждого блока 8 символов, и имеет длину 8, поэтому нужная часть строки задаётся выражением s.AsSpan(n * 8, 8). (Для старых версий C# придётся использовать менее эффективный Substring, который аллоцирует новую строку-копию.)
Далее, полученный кусок надо распарсить как 16-ричное число. Для этого берём uint.Parse с соответствующими параметрами.
Получившуюся ленивую последовательность материализуем в массив при помощи .ToArray().
Всё!
P. S.: В будущих версиях .NET будет добавлен удобный метод Chunk, позволяющий «нарезать» последовательность на куски фиксированного размера, и можно будет написать изящнее:
s.Chunk(8)
.Select(part => uint.Parse(part,
NumberStyles.HexNumber,
CultureInfo.InvariantCulture))
.ToArray();
Впрочем, сейчас похожая функциональность есть в пакете morelinq под названием Batch.
P. P. S.: Поскольку новый System.Range не реализует интерфейс IEnumerable<T>, мне прошлось использовать более древний Enumerable.Range вместо (0..s.Length/8).Select...