我有一个Wyam管道,名为"帖子"装满文件。其中一些文档具有Tags
元值,这是一个以逗号分隔的标记列表。例如,我们假设它有三个文档,其中Tags
元:
gumby,pokey
gumby,oscar
oscar,kermit
我希望在"帖子"中的所有文档中找到一个新的管道,其中包含一个文档,用于每个唯一标记。管道。这些文档应该在名为TagName
的元值中包含标记。
因此,上述值应该会产生一个由四个文档组成的新管道,其中TagName
元值为:
gumby
pokey
oscar
kermit
这是我的解决方案。 这在技术上有效,但我觉得它效率低下,而且我非常确定必须有更好的方法。
Documents(c => c.Documents["Posts"]
.Select(d => d.String("Tags", string.Empty))
.SelectMany(s => s.Split(",".ToCharArray()))
.Select(s => s.Trim().ToLower())
.Distinct()
.Select(s => c.GetNewDocument(
string.Empty,
new List<KeyValuePair<string, object>>()
{
new KeyValuePair<string, object>("TagName", s)
}
))
)
所以,我正在调用Documents
并传递ContextConfig
:
Tags
元值(现在我有一个字符串集合)TagName
值(我应该最终得到一组新文档)再次,这是有效的。但是有更好的方法吗?
答案 0 :(得分:1)
这实际上并不坏 - 这里的部分挑战是将逗号分隔的标签列表转换为可由LINQ表达式或类似方法处理的内容。那部分可能是不可避免的,占你表达中的3行。
尽管如此,Wyam确实在ToLookup()
扩展程序中提供了一些帮助(请参阅本页底部:http://wyam.io/getting-started/concepts)。
以下是它的外观(此代码来自一个独立的LINQPad脚本,需要进行调整才能在Wyam配置文件中使用):
public void Main()
{
Engine engine = new Engine();
engine.Pipelines.Add("Posts",
new PostsDocuments(),
new Meta("TagArray", (doc, ctx) => doc.String("Tags")
.ToLowerInvariant().Split(',').Select(x => x.Trim()).ToArray())
);
engine.Pipelines.Add("Tags",
new Documents(ctx => ctx.Documents["Posts"]
.ToLookup<string>("TagArray")
.Select(x => ctx.GetNewDocument(new MetadataItems { { "TagName", x.Key } }))),
new Execute((doc, ctx) =>
{
Console.WriteLine(doc["TagName"]);
return null;
})
);
engine.Execute();
}
public class PostsDocuments : IModule
{
public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
{
yield return context.GetNewDocument(new MetadataItems { { "Tags", "gumby,pokey" } });
yield return context.GetNewDocument(new MetadataItems { { "Tags", "gumby,oscar" } });
yield return context.GetNewDocument(new MetadataItems { { "Tags", "oscar,kermit" } });
}
}
输出:
gumby
pokey
oscar
kermit
很多只是用于设置假测试环境的内务处理。您正在寻找的重要部分是:
engine.Pipelines.Add("Tags",
new Documents(ctx => ctx.Documents["Posts"]
.ToLookup<string>("TagArray")
.Select(x => ctx.GetNewDocument(new MetadataItems { { "TagName", x.Key } }))),
// ...
);
请注意,我们仍然需要将逗号分隔标记列表添加到数组中 - 它只是在早期发生在&#34;帖子&#34;管道