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><![CDATA[ Walmart ]]></name>
<instock><![CDATA[ true ]]></instock>
</retailer>
<retailer>
<name><![CDATA[ Soap.com ]]></name>
<instock><![CDATA[ true ]]></instock>
</retailer>
<retailer>
<name><![CDATA[ Restockit ]]></name>
<instock><![CDATA[ true ]]></instock>
</retailer>
<retailer>
<name><![CDATA[ Drugstore.com ]]></name>
<instock><![CDATA[ true ]]></instock>
</retailer>
<retailer>
<name><![CDATA[ Walgreens.com ]]></name>
<instock><![CDATA[ true ]]></instock>
</retailer>
<retailer>
<name><![CDATA[ Amazon ]]></name>
<instock><![CDATA[ true ]]></instock>
</retailer>
<retailer>
<name><![CDATA[ Target ]]></name>
<instock><![CDATA[ true ]]></instock>
</retailer>
</retailers>
source to share
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();
source to share
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();
source to share