RSS

Advent LINQ (5): Flatten

05 12月

Advent LINQ (3)で、フォルダを探索しながらファイルを列挙するFilesAsEnumerableを作った。このような、木構造のシーケンスを探索するというシチュエーションは、色々ありそうだ。なので、このアルゴリズムを一般化する事を考える。

public static class LinqExtensions
{
	public static IEnumerable<U> Flatten<T, U>(
		this T node,
		Func<T, IEnumerable<T>> predictBySubNode,
		Func<T, IEnumerable<U>> predictByNode)
	{
		var bySubNode =
			from subNode in predictBySubNode(node)
			from childNode in Flatten(subNode, predictBySubNode, predictByNode)
			select childNode;

		var byNode =
			from childNode in predictByNode(node)
			select childNode;

		return bySubNode.Concat(byNode);
	}
}

これを使ってファイルの探索を行うには、以下のように記述する。

var baseDirectory = new DirectoryInfo(@"C:\project");
foreach (var file in baseDirectory.Flatten(
	directory => directory.GetDirectories(),
	directory => directory.GetFiles("*.cs")))
{
	Console.WriteLine(file.FullName);
}

XmlDocumentから、テキストノードを抜き出してみる。

var document = new XmlDocument();
document.Load(@"C:\project\data.xml");
foreach (var text in document.DocumentElement.Flatten(
	element => element.SelectNodes("*").Cast<XmlElement>(),
	element => element.SelectNodes("text()").Cast<XmlText>()))
{
	Console.WriteLine(text.Value);
}

もちろん、XDocumentにも応用可能。

広告
 
コメントする

投稿者: : 2013/12/05 投稿先 .NET, LINQ

 

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

 
%d人のブロガーが「いいね」をつけました。