Добавить коллекцию в конец IOrderedEnumerable

В настоящее время у меня есть куча конфигурационных файлов, которые мне нужно загрузить в IOrderedEnumerable. Мой текущий подход выглядит так:

foreach (var item in configFiles)
{
    XDocument myxml = XDocument.Load(item);
    var items = myxml.Root.Elements("Item");
    Items = items.OrderBy(x => x.Attribute("ID").Value);
    ItemsLength += Items.Count();              
}

Проблема в том, чтобы вместо Items равно items.OrderBy(x => x.Attribute("ID").Value) Я хотел бы присоединить это к концу существующего в настоящее время IOrderedEnumerable, поэтому я не перезаписываю его каждый раз, когда загружаю новый XDocument и получаю из него все элементы. Как бы я это сделал?

РЕДАКТИРОВАТЬ: я знаю, что если я изменю это ItemsLength += Items.Count(); больше не будет функционировать должным образом. Это то, что я буду менять самостоятельно.

2 ответа

Решение

Вы можете сделать все это декларативно:

Items = configFiles.Select((item, index) => new { Doc = XDocument.Parse(item),
                                                  Index = index })
                   .SelectMany(pair => pair.Doc.Root.Elements("Item")
                                           .Select(x => new { Item = x, 
                                                              Index = pair.Index }))
                   .OrderBy(pair => pair.Index)
                   .ThenBy(pair => (string) pair.Attribute("ID"))
                   .Select(pair => pair.Item);

Это в основном находит все элементы, но запоминает, в какой конфигурации находится каждый.

Или просто создайте List<XElement> и добавьте содержимое каждого элемента:

var items = new List<XElement>();
foreach (var item in configFiles)
{
    items.AddRange(XDocument.Parse(item)
                            .Root.Elements("Item")
                            .OrderBy(x => (string) x.Attribute("ID")));
}
Items = items;

В некотором смысле это менее элегантно, но, вероятно, легче понять:)

Если вы можете изменить Items быть типом IEnumerable скорее, чем IOrderedEnumerableВы могли бы использовать Concat:

Items = Items.Concat(items.OrderBy(x => x.Attribute("ID").Value));

Это позволит сохранить элементы отсортированы по ID в своем собственном документе.

Обратите внимание, что с помощью Concat в цикле может ухудшить производительность. Вам лучше объявить Items как IListи звонит ToList в конце каждой итерации:

Items.AddRange(items.OrderBy(x => x.Attribute("ID").Value));
Другие вопросы по тегам