Creating a ConcurrentDictionary<string, ConcurrentQueue<decimal>> and keeping a specified ordering

52 views Asked by At

I'm trying to return an ordered version of a ConcurrentDictionary<string, ConcurrentQueue> using the below code:

    public ConcurrentDictionary<string, ConcurrentQueue<decimal>> 
    GetBestList(ConcurrentDictionary<string, ConcurrentQueue<decimal>> inputList)
    {
        var bestList = new ConcurrentDictionary<string, ConcurrentQueue<decimal>>(
                inputList.Where(x => x.Value != null && x.Value.Count >= 2).
                OrderByDescending(x => CalculateAverage(x.Value)));

        return bestList;
    }

    public decimal CalculateAverage(ConcurrentQueue<decimal> inputList)
    {
        return inputList.Average();
    }

The above code returns a jumbled mess and doesn't keep the same ordering so I tried to change it. I found this question and used the code from the answer to try this and it works correctly with keeping the correct ordering but it is a Dictionary and not a ConcurrentDictionary

var bestList = inputList.Where(x => x.Value != null && x.Value.Count >= 2).
               OrderByDescending(x => CalculateAverage(x.Value)).
               ToDictionary(pair => pair.Key, pair => pair.Value);

I then found this question and used code from the answer to create an extension method for ToConcurrentQueue but it also doesn't keep the same ordering and returns a jumbled mess.

public static class ConcurrentDictionaryExtensions
{
    public static ConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
    {
        if (source == null) throw new ArgumentNullException("source");
        if (keySelector == null) throw new ArgumentNullException("keySelector");
        if (elementSelector == null) throw new ArgumentNullException("elementSelector");

        ConcurrentDictionary<TKey, TElement> d = new ConcurrentDictionary<TKey, TElement>(comparer ?? EqualityComparer<TKey>.Default);
        foreach (TSource element in source)
            d.TryAdd(keySelector(element), elementSelector(element));

        return d;
    }

    public static ConcurrentDictionary<TKey, TSource> ToConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
    {
        return ToConcurrentDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, null);
    }

    public static ConcurrentDictionary<TKey, TSource> ToConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
    {
        return ToConcurrentDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, comparer);
    }

    public static ConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
    {
        return ToConcurrentDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector, null);
    }

    internal class IdentityFunction<TElement>
    {
        public static Func<TElement, TElement> Instance
        {
            get { return x => x; }
        }
    }

}

I have exhausted all of my ideas so I'm hoping someone here can let me know how I can return a ConcurrentDictionary using the same ordering.

0

There are 0 answers