Reputation: 412
I have to sort a namevaluecollection(Items usually 5 to 15) Against an enum(having items more than 60). Right now I am using this extension function, Anyone have better idea to write this code....
public static NameValueCollection Sort(this NameValueCollection queryString, Type orderByEnumType, bool excludeZeroValues)
{
NameValueCollection _processedQueryString = HttpUtility.ParseQueryString("");
if (queryString.HasKeys())
{
SortedList<int, KeyValuePair<string, string>> querySortedList = new SortedList<int, KeyValuePair<string, string>>();
string[] enumKeys = Enum.GetNames(orderByEnumType);
int counter = 1000;
foreach (string key in queryString)
{
string value = queryString[key];
if (enumKeys.Contains(key, StringComparer.CurrentCultureIgnoreCase))
{
int order = (int)Enum.Parse(orderByEnumType, key, true);
querySortedList.Add(order, new KeyValuePair<string, string>(key, value));
}
else
{
querySortedList.Add(counter, new KeyValuePair<string, string>(key, value));
counter++;
}
}
foreach (KeyValuePair<int, KeyValuePair<string, string>> kvp in querySortedList)
{
if (!kvp.Value.Value.IsNullOrEmpty() && !kvp.Value.Key.IsNullOrEmpty())
{
if (!excludeZeroValues || kvp.Value.Value != "0")
{
_processedQueryString.Add(kvp.Value.Key, System.Web.HttpUtility.UrlEncode(kvp.Value.Value));
}
}
}
}
return _processedQueryString;
}
This works like this
public enum OrderEnum
{
key1=1,
key2=20,
key3=3,
//note
key4=100,
key5=2,
key6=6,
key7,
key8,
key9
}
public void Test()
{
NameValueCollection col1 = new NameValueCollection();
col1.Add("key1", "value1");
col1.Add("key9", "value1");
col1.Add("key3", "value1");
col1.Add("key5", "value1");
Response.Write(col1.Sort(typeof(OrderEnum)).ToString());
//out put: key1=value1&key5=value1&key3=value1&key9=value1
}
This is should also work
public void Test2()
{
NameValueCollection col1 = new NameValueCollection();
col1.Add("key1", "value1");
col1.Add("key-x", "value1");
col1.Add("key-y", "value1");
col1.Add("key9", "value1");
col1.Add("key3", "value1");
col1.Add("key5", "value1");
col1.Add("key-z", "value1");
Response.Write(col1.Sort(typeof(OrderEnum)).ToString());
//out put: key1=value1&key5=value1&key3=value1&key9=value1&key-x=value1&key-y=value1&key-z=value1
}
Upvotes: 0
Views: 2200
Reputation: 292465
You could do something like that :
public static NameValueCollection SortByEnum<TEnum>(this NameValueCollection source) where TEnum : struct
{
var orderedKeys = source.Keys.Cast<string>().OrderBy(k => Enum.IsDefined(typeof(TEnum), k) ? Convert.ToInt32(Enum.Parse(typeof(TEnum), k)) : int.MaxValue);
var ordered = new NameValueCollection();
foreach(var key in orderedKeys) ordered.Add(key, source[key]);
return ordered;
}
Upvotes: 0
Reputation: 412
I finally Came to conclusion with this solution
public static NameValueCollection SortByEnum<TEnum>(this NameValueCollection source) where TEnum : struct
{
var orderedKeys = source.Keys.Cast<string>().OrderBy(k => ((Enum.IsDefined(typeof(TEnum), k)) ? ((int)Enum.Parse(typeof(TEnum), k)) : int.MaxValue));
var ordered = HttpUtility.ParseQueryString("");
foreach (var key in orderedKeys)
{
ordered.Add(key, source[key]);
}
return ordered;
}
This will resolve all my issues Thanks @thomas @ramesh
Upvotes: 0
Reputation: 65877
I think its better to convert your namevaluecollection into List of keyvaluepairs and apply a simple LINQ order by operation, thats quick and simple.
Add a new extension method to convert your namevaluecoll into list of keyvaluepairs
public static List<KeyValuePair<string, string>> ToPairs(this System.Collections.Specialized.NameValueCollection collection)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
return collection.Cast<string>().Select(key => new KeyValuePair<string, string>(key, collection[key])).ToList();
}
And just apply the linq order by over this object, something like this
System.Collections.Specialized.NameValueCollection col1= new System.Collections.Specialized.NameValueCollection();
col1.Add("key1", "value1");
col1.Add("key-x", "value2");
col1.Add("key-y", "value3");
col1.Add("key9", "value4");
col1.Add("key3", "value5");
col1.Add("key5", "value6");
col1.Add("key-z", "value7");
var nvc = col1.ToPairs();
// To order the items based on key in descending order
var orderedbykey=nvc.OrderByDescending(x => x.Key).ToList();
// To order the items based on value in descending order
var orderedbyval=nvc.OrderByDescending(x => x.Value).ToList();
//or order by ur custom enum key
var orderbyEnumKeys = colc.OrderBy(x =>
{
int en;
try
{
en = (int)Enum.Parse(typeof(OrderEnum), x.Key);
}
catch (Exception ex)
{
return int.MaxValue;
}
return en;
}).ToList();
Hope this helps..
Upvotes: 1