2016-11-10 4 views
-1

Мне нужно просмотреть документ Word и получить некоторые текстовые поля, чтобы их изменить.Упростить двойную команду foreach

Но мне нужно посчитать их раньше, и я думаю, что то, что я написал, действительно неэффективно.

Я хотел бы знать, если это возможно, чтобы упростить следующим образом:

foreach (Microsoft.Office.Interop.Word.HeaderFooter OHeader in documentOld.Sections[1].Headers) 
{ 
    foreach (Microsoft.Office.Interop.Word.Shape shape in OHeader.Shapes) 
    { 
     if (shape.Name.Contains("Text Box")) 
     { 
      listTextBox.Add(new KeyValuePair<string, string>(shape.Name.ToString(), shape.TextFrame.TextRange.Text.ToString())); 
     } 
    } 
} 

int count = listTextBox.Count(); 

Я хочу знать, как много элементов, которые содержат «Text Box» находятся в Shapes.

ответ

5

Я вижу два способа, которыми вы можете это сделать.

Использование LINQ синтаксис:

var count = (
    from OHeader in documentOld.Sections[1].Headers 
    from shape in OHeader.Shapes 
    where shape.Name.Contains("Text Box")).Count(); 

Или, используя методы IEnumerable расширения:

var count = documentOld.Sections[1].Headers 
       .SelectMany(h => h.Shapes) 
       .Count(s => s.Name.Contains("Text Box")); 

Обратите внимание, что ваша версия является неэффективным в том, что она создает список и KeyValuePair s без необходимости, учитывая, что вы только хотите подсчитать количество фигур, которые соответствуют некоторому условию. Другое, что вложенные блоки foreach хороши для производительности, но могут не иметь удобочитаемости по сравнению с эквивалентами LINQ.

Также обратите внимание, что я не тестировал код выше.

+1

Стоит отметить, что код в вопросе использует 'Contains', но вопрос запрашивает равные значения, поэтому можно использовать' Equals' – TheLethalCoder

1

Сохранение кода одинаково с помощью петель foreach. Все, что вам нужно сделать, это иметь переменную count перед циклами и увеличивать ее каждый раз, когда вы находите совпадение.

int count = 0; 
foreach (Microsoft.Office.Interop.Word.HeaderFooter OHeader in documentOld.Sections[1].Headers) 
{ 
    foreach (Microsoft.Office.Interop.Word.Shape shape in OHeader.Shapes) 
    { 
     if (shape.Name.Contains("Text Box")) 
     { 
      ++count; 
     } 
    } 
}