๋ท๋ท 7 ๊ธฐ์ค ReadOnlySpan์๋ ์์ง Split์ด ์์ต๋๋ค. ReadOnlySpan์ ํ์ฉํ๋ฉด Parse ๋ฑ ๋ฌธ์์ด ์ฒ๋ฆฌ์ ๋ถํ์ํ ํ ํ ๋น์ ์ต์ํํ ์ฑ๋ก ์์ ํ ์ ์์ง ์์๊น ํ๋ ์๊ฐ์ด ๋ญ๋๋ค.
์ฌ์ค ReadOnlySpan์๋ ์ด๋ฏธ IndexOf๊ฐ ์๊ธฐ ๋๋ฌธ์, ๊ฐ๋จํ ์์ค์ Split์ ๊ตฌํํ๋ ๊ฒ์ ๊ทธ๋ ๊ฒ ์ด๋ ค์ด ์ผ์ด ์๋๋๋ค. IndexOf๋ฅผ ์ด์ฉํด separator์ index๋ฅผ ๊ฐ์ ธ์จ ๋ค์, ์๋ณธ ๋ฌธ์์ด์ Slice ํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
public static SpanSplitEnumerator Split(this ReadOnlySpan<char> src, char separator) => new(src, new char[] { separator });
public static SpanSplitEnumerator Split(this ReadOnlySpan<char> src, ReadOnlySpan<char> separator) => new(src, separator);
public ref struct SpanSplitEnumerator
{
private ReadOnlySpan<char> _string;
private readonly ReadOnlySpan<char> _separator;
private int _index;
private bool _isEnd;
public SpanSplitEnumerator(ReadOnlySpan<char> source, ReadOnlySpan<char> separator)
{
_string = source;
_separator = separator;
_index = 0;
_isEnd = false;
}
public SpanSplitEntry Current { get; private set; }
public SpanSplitEnumerator GetEnumerator() => this;
public bool MoveNext()
{
if (_isEnd)
{
return false;
}
int index = _string.IndexOf(_separator);
if (index >= 0)
{
Current = new SpanSplitEntry(_string[..index], _index++);
_string = _string[(index + _separator.Length)..];
}
else
{
Current = new SpanSplitEntry(_string, _index++);
_string = ReadOnlySpan<char>.Empty;
_isEnd = true;
}
return true;
}
public readonly ref struct SpanSplitEntry
{
internal SpanSplitEntry(ReadOnlySpan<char> chars, int index)
{
Chars = chars;
Index = index;
}
public ReadOnlySpan<char> Chars { get; }
public int Index { get; }
}
}
๋ง๋๋ ๊น์ foreach ๋ฌธ์์ index๋ฅผ ์จ์ผ ํ ์ผ์ด ์์ ๋ ๋ช ๋ฒ์งธ ๋ฌธ์์ด์ธ์ง ๊ฐ์ ธ์ฌ ์ ์๋๋ก index๋ ์ถ๊ฐํด ๋ดค์ต๋๋ค.