在c#中将嵌套for循环转换为声明式

时间:2016-12-01 22:34:03

标签: c# linq

如何将嵌套的for循环转换为声明式样式?

示例代码:

List<String> words = new List<String>();
Books.ForEach(book => book.ForEach(page => 
                                  page.ForEach(line =>words.Add(CreateWord(book, page, line)))));

1 个答案:

答案 0 :(得分:1)

如果您希望提高可读性,那么您可以逐步进行操作。首先将每个book条目扩展为一系列(书,页)对。然后每对转换为三元组(书籍,页面,行)并使用CreateWords方法将其转换为字符串。

代码告诉的不仅仅是文字,这就是它的外观:

List<string> words = Books
    .SelectMany(book => book.Pages.Select(page => new
        {
            Book = book,
            Page = page
        }))
    .SelectMany(pair => pair.Page.Lines.SelectMany(line =>
        new CreateWords(book, page, line));

这可能不是LINQ代码中最易读的部分。但它经常就是这样。 LINQ倾向于生成紧凑但丑陋的映射代码。

在相关的说明中,我想知道CreateWords方法的目的是什么?如果它只返回一系列字符串,则不需要使用书籍,页面和行进行整个冒险。如果我是对的,您可以将CreateWords更改为仅接收表示该行的单个字符串 - 它根本不需要书籍或页面对象。在这种情况下,查询将被简化:

List<string> words = Books
    .SelectMany(book => book.Pages)
    .SelectMany(page => page.Lines)
    .SelectMany(line => CreateWords(line));