How do I order a list based on a custom sequence?

I am getting some xml data as a list in the following uniqueCD variable . After receiving all the data, I want it to reorder the data based on my own requirement, and the order should look like this:

  • Amazon
  • Soap.com
  • Drugstore.com
  • Walmart
  • purpose


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

      

Getting Xml data from a list:

<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


source to share


3 answers


Unless you have any business logic where you could use an algorithm (for example alphabetically), I would recommend using a custom sorting extension method. You'll have to hard-code it so it won't be fancy or fulfilling, but it will work:

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

}

      



And then call this method from your linq statement:

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

      

+2


source


You can try to map the retailer name to the ranking priority in a suitable data structure, for example Dictionary<string, int>

:

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

      



Then create a function to get retail ranking based on dictionary matching and use the function for OrderBy

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

      

+1


source


Define an array with custom sort values ​​and then use the array index for the order value.

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

      

0


source







All Articles