2014-09-10 4 views
3

Я получаю некоторые данные xml как список ниже uniqueCD переменная. После того, как все данные, которые я хочу, чтобы изменить порядок следования данных, основанных на моем требовании, и порядок должен быть как:Как заказать список на основе пользовательской последовательности?

  1. Amazon
  2. Soap.com
  3. Drugstore.com
  4. Walmart
  5. Target


var uniqueCD = (from n in xdoc.Descendants("retailer") 
        .Where(x => x.Element("instock").Value.Contains("true")) 
        select n).Distinct(new XElementComparer()).ToList(); 

Xml данные Geting из списка:

<retailers> 
    <retailer> 
    <name>&lt;![CDATA[ Walmart ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Soap.com ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Restockit ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Drugstore.com ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Walgreens.com ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Amazon ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
    <retailer> 
    <name>&lt;![CDATA[ Target ]]&gt;</name> 
    <instock>&lt;![CDATA[ true ]]&gt;</instock> 
    </retailer> 
</retailers> 
+2

Этот "заказ" выглядит абсолютно произвольным ... Как/Где вы определили эту последовательность? – Belogix

+0

Вы управляете XML? Можете ли вы связать какие-то метаданные с каждым розничным торговцем, которые вы можете использовать для порядка сортировки? Например (учитывая, что вы контролируете источник XML), вы можете добавить тег '' в XML и использовать '.By()' LINQ для сортировки списка. –

+0

actly m чтение нескольких xml и формирование этого как seprate xml. –

ответ

2

Если у вас нет какой-либо бизнес-логики, где вы могли бы dervive алгоритм (т.е. в алфавитном порядке), то я бы рекомендовал метод пользовательского расширения, чтобы сделать ваш сортировка. Вы должны жестко закодировать его, так что он не будет фантазии или производительным, но он будет работать:

public static IEnumerable<XElement> CustomSort(this IList<XElement> elms) 
{ 
    yield return elms.FirstOrDefault(x => x.Name == "Amazon"); 
    yield return elms.FirstOrDefault(x => x.Name == "Soap.com"); 

    //etc 

} 

И затем вызвать этот метод из вашего Linq заявление:

 (from n in xdoc.Descendants("retailer") 
       .Where(x => x.Element("instock").Value.Contains("true")) 
       select n) 
     .Distinct(new XElementComparer()).ToList() 
     .CustomSort().ToList(); 
+0

Можете ли вы рассказать мне, что произойдет, если «soap.com» не будет в моих существующих данных ... будет ли он игнорировать его или выбросить ошибку. –

+0

В этом случае он будет возвращать 'null' для любых отсутствующих значений –

1

Вы можете попытаться указать отображение имени ритейлера ранжировать предпочтения в подходящей структуры данных, например Dictionary<string, int>:

private Dictionary<string, int> retailerRank = new Dictionary<string, int>() 
               { 
                {"Amazon", 1}, 
                {"Soap.com", 2}, 
                ...... 
                ...... 
               }; 

Затем создайте функцию, чтобы получить ритейлер ранга на основе словаря отображения, а также использовать функцию для OrderBy работы в вашем LINQ:

private int getRetailerRank(string retailer) 
{ 
    var match = retailerRank.FirstOrDefault(o => retailer.Contains(o.Key)); 
    return match.Value == 0 ? int.MaxValue : match.Value; 
} 
.... 
var uniqueCD = (from n in xdoc.Descendants("retailer") 
           .Where(x => x.Element("instock").Value.Contains("true")) 
       select n 
       ).Distinct(new XElementComparer()) 
       .OrderBy(o => getRetailerRank(o.Element("name").Value)) 
       .ToList(); 
0

Определяет массив со значениями пользовательских сортировок, а затем использовать индекс массива для заказа стоимость.

var ordering = new [] {"Amazon", "Soap.com"}; 
var orderedCollection = coll.OrderBy(item => Array.IndexOf(ordering, item.SomeProperty)); 
Смежные вопросы