C# Sorted List by Value with Object

前端 未结 9 1013
失恋的感觉
失恋的感觉 2021-01-21 20:06

I\'m trying to create an \"ordered\" cache of objects in C#, where the order is determined by how many times that has been accessed.

I\'ve looked into Dictionary, Sorted

9条回答
  •  耶瑟儿~
    2021-01-21 20:17

    Wonder if you are after something like this.

    You could store two sets of relationships; all the objects, by key to make retrieval fast, and all of the objects by Hits to store the ordering. This has the added advantage of speeding up access - you can get the Result, the Hits, and therefore it's current and next index quite quickly.

    When Getting a result, we lock the access to ensure we change it's order atomically, then return the object. We also cheat when writing out the number of hits; we know what the most popular is and then we can just walk backwards through that collection - could really even extract the keys to a List, sort it, then iterate through that.

    public class PopularityContest{
    
        private Dictionary> PopularityContainer { get; set; }
    
        private Dictionary ResultContainer { get; set; }
    
        private int MaxPopularity = 0;
    
        public PopularityContest(){
            PopularityContainer = new Dictionary>();
            ResultContainer = new Dictionary();
        }
    
        private Object _SyncLock = new Object();
    
        public Result GetResult(string resultKey)
        {
    
          Result result = ResultContainer[resultKey];
    
          lock(_SyncLock)
          {
    
            int currentHits = result.Hits;
    
            if(PopularityContainer.ContainsKey(currentHits) && PopularityContainer[currentHits].Contains(result))
            {
               PopularityContainer[currentHits].Remove(result);
            }
    
            if(!PopularityContainer.ContainsKey(currentHits + 1))
            {
              PopularityContainer.Add(currentHits + 1, new List());
            }
    
            PopularityContainer[currentHits + 1].Add(Result);
    
            if((currentHits + 1) > MaxPopularity) { MaxPopularity = currentHits + 1;}
    
          }
    
          return result;
    
        }
    
    
        public void WritePopularity()
        {
    
          //Here could also extract the keys to a List, sort it, and walk that.
          //Note, as this is a read operation, dependent upon ordering, you would also consider locking here.
    
          for(int i = MaxPopularity; i >= 0; i--)
          {
             if(PopularityContainer.Contains(i) && PopularityContainer[i].Count > 0)
             {
                //NB the order of items at key[i] is the order in which they achieved their popularity
                foreach(Result result in PopularityContainer[i])
                {
                Console.WriteLine(String.Format("{0} has had {1} hits", result.ToString(), i));
                }
             }
    
          }
        }
    
    }
    

提交回复
热议问题