Сортировать NameValueCollection против Enum - PullRequest
0 голосов
/ 23 февраля 2010

Я должен отсортировать коллекцию имен по значению ( Позиции обычно от 5 до 15 ) Против перечисления ( с элементами более 60) . Прямо сейчас я использую эту функцию расширения, у кого есть идея лучше написать этот код ....

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

Это работает так

    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
    }

Это тоже должно работать

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
    }

Ответы [ 3 ]

1 голос
/ 23 февраля 2010

Я думаю, что лучше преобразовать вашу коллекцию namevalue в Список значений ключей и применить простой порядок LINQ по операции, это быстро и просто.

Добавить новый метод расширения для преобразования вашего namevaluecoll в список пар ключей-значений

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

И просто примените порядок linq к этому объекту, что-то вроде этого

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

Надеюсь, это поможет ..

0 голосов
/ 23 февраля 2010

Я наконец пришел к выводу с этим решением

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

Это решит все мои проблемы Спасибо @thomas @ ramesh

0 голосов
/ 23 февраля 2010

Вы можете сделать что-то подобное:

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;
}
...