環境
.NET 10、C#
コード
一例として、2つのパスが親子であるかどうかを判定するコードを作りました。ReadOnlySpan<T>の場合、分割の結果をRangeの列挙子で返すところがキーですね。
using Path = System.IO.Path;
namespace Common.IO
{
/// <summary>
/// パス情報を表す string の操作を提供します。
/// </summary>
public static class PathHelper
{
private static readonly char[] s_directorySeparatorChars = Path.DirectorySeparatorChar == Path.AltDirectorySeparatorChar
? [Path.DirectorySeparatorChar]
: [Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar];
/*
public static bool IsParentOf(string parentPath, string childPath)
{
if (string.IsNullOrEmpty(parentPath) || string.IsNullOrEmpty(childPath))
{
return false;
}
parentPath = Path.TrimEndingDirectorySeparator(parentPath);
childPath = Path.TrimEndingDirectorySeparator(childPath);
if (parentPath.Length >= childPath.Length)
{
return false;
}
string[] parentSegments = parentPath.Split(s_directorySeparatorChars);
string[] childSegments = childPath.Split(s_directorySeparatorChars);
return (parentSegments.Length < childSegments.Length)
&& childSegments.Take(parentSegments.Length).SequenceEqual(parentSegments, StringComparer.OrdinalIgnoreCase);
}
*/
/// <summary>
/// parentPath が childPath の親ディレクトリーであるかどうかを返します。
/// </summary>
/// <param name="parentPath"></param>
/// <param name="childPath"></param>
/// <returns></returns>
public static bool IsParentOf(ReadOnlySpan<char> parentPath, ReadOnlySpan<char> childPath)
{
if (parentPath.IsEmpty || childPath.IsEmpty)
{
return false;
}
parentPath = Path.TrimEndingDirectorySeparator(parentPath);
childPath = Path.TrimEndingDirectorySeparator(childPath);
if (parentPath.Length >= childPath.Length)
{
return false;
}
// パスを区切り文字で分割して、childPath の先頭に parentPath が含まれているかどうかを判断します。
MemoryExtensions.SpanSplitEnumerator<char> parentSegments = parentPath.SplitAny(s_directorySeparatorChars);
MemoryExtensions.SpanSplitEnumerator<char> childSegments = childPath.SplitAny(s_directorySeparatorChars);
while (parentSegments.MoveNext())
{
if (!childSegments.MoveNext())
{
return false;
}
ReadOnlySpan<char> parentSegment = parentPath[parentSegments.Current];
ReadOnlySpan<char> childSegment = childPath[childSegments.Current];
if (!parentSegment.Equals(childSegment, StringComparison.OrdinalIgnoreCase))
{
return false;
}
}
return childSegments.MoveNext();
}
}
}
0 件のコメント:
コメントを投稿