如何根据自定义顺序订购listitem?

时间:2014-09-10 13:06:42

标签: c# xml linq-to-xml

我在下面的 uniqueCD 变量中获取了一些xml数据作为列表。获取所有数据后,我希望它根据我自己的要求更改数据的顺序,顺序应该是:

  1. 亚马逊
  2. Soap.com
  3. Drugstore.com
  4. 沃尔玛
  5. 目标

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

    从列表中提取Xml数据:

    <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>
    

3 个答案:

答案 0 :(得分:2)

如果您没有任何业务逻辑可以实现算法(即按字母顺序排列),那么我建议您使用自定义扩展方法进行排序。您必须对其进行硬编码,因此它不会花哨高性能,但它会起作用:

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();

答案 1 :(得分:1)

您可以尝试在合适的数据结构中指定零售商名称到排名首选项的映射,例如Dictionary<string, int>

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

然后根据字典映射创建一个获取零售商排名的函数,并在LINQ中使用OrderBy操作函数:

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();

答案 2 :(得分:0)

使用自定义排序值定义数组,然后使用数组索引作为排序值。

var ordering = new [] {"Amazon", "Soap.com"};
var orderedCollection = coll.OrderBy(item => Array.IndexOf(ordering, item.SomeProperty));