当前位置: 首页 > 编程语言 > C#

C#按值对象排序列表分享

时间:2023-04-10 10:59:06 C#

C#学习教程:C#按值对象排序列表我查看了Dictionary、SortedList和SortedDictionary,它们非常接近,但不是我想要的。我想要一个所有以前缓存的项目的列表,可以使用getHits()方法来确定缓存项目的顺序。然后我可以按名称访问该缓存并增加该项目的查看次数。简化示例(在伪C#中):classResult{publicintHits=0;公共字符串名称=“”;publicvoidIncreaseHits(){this.hits++;}publicResult(Stringname){this.name=name;}}classProgram{publicMagicSortableTypeMyCache;//使用什么结构?publicmain(){我的缓存。Add(newResult("我的结果1"));我的缓存。Add(newResult("我的结果2"));MyCache.Add(newResult("我的结果3"));MyCache['我的结果2'].IncreaseHits();MyCache['我的结果2'].IncreaseHits();MyCache['我的结果3'].IncreaseHits();MyCache.SortDesc();//真正的C#等价物是什么?foreach(MyCache中的结果结果){Console.Write(result.Name+"-hits"+result.Hits);}}}输出:我的结果2-命中2我的结果3-命中1我的结果1-命中0当我需要这样的东西时,我创建了我称之为MruDictionary的东西。它由LinkedList和Dictionary>组成(其中T是对象的类型,对象键是字符串类型)。访问是通过字典。当一个项目被访问时,它会移动到列表的头部。添加项目时,它会添加到列表的开头。如果列表大小超过设置的最大值,则删除列表中的最后一个节点。这很好用。这些物品的使用次数没有先后顺序,而是严格按照MRU顺序排列。这通常会将最常用的项目保留在缓存中,但如果长时间未使用,则会刷新常用项目。出于我的目的,这非常有效。我写了一篇关于它的文章。有关说明的完整信息,请访问http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=626。如果您确实需要,添加命中应该很容易。根据您的伪代码,这似乎有效:varMyCache=newDictionary{{"Myresult1",newResult("Myresult1")},{"Myresult2",newResult("Myresult2")},{"我的结果3",newResult("我的结果3")},{"我的结果4",newResult("我的结果4")}};MyCache["我的结果2"].IncreaseHits();MyCache["我的结果2"].IncreaseHits();MyCache["我的结果3"].IncreaseHits();foreach(varresultinMyCache.OrderByDescending(x=>x.Value.Hits)){Console.WriteLine(result.Value.Name+"-hits"+result.Value.Hits);我猜你需要这样的东西:SortedDictionaryMyCache=newSortedDictionary();stringstrKey="NewResult";如果(MyCache.ContainsKey(strKey)){MyCache[strKey]=MyCache[strKey]+1;}else{MyCache.Add(strKey,1);但是SortedDictionary按键排序SortedDictionary-MSDN说键/值按对的键集合排序。您可以将字典提取到List>中,然后根据值对它们进行排序,例如:List>list=MyCache.ToList();foreach(variteminlist.OrderByDescending(r=>r.Value)){控制台。WriteLine(item.Key+"-hits"+item.Value);}所以你可以:classProgram{publicstaticSortedDictionaryMyCache=newSortedDictionary();staticvoidMain(string[]args){AddToDictionary("Result1");AddToDictionary("结果1");AddToDictionary("结果2");AddToDictionary("结果2");AddToDictionary("结果2");AddToDictionary("结果3");列表>列表=MyCache.ToList();foreach(variteminlist.OrderByDescending(r=>r.Value)){Console.WriteLine(item.Key+"-hits"+item.Value);}}publicstaticvoidAddToDictionary(stringstrKey){if(MyCache.ContainsKey(strKey)){MyCache[strKey]=MyCache[strKey]+1;}else{MyCache.Add(strKey,1);然后输出将是:Result2-hits3Result1-hits2Result3-hits1不管你喜不喜欢这样的事情。您可以存储两组关系;所有对象,通过键快速检索,所有对象存储按命中排序。这具有加快访问速度的额外优势-您可以非常快速地获得Result和Hits,因此它是当前索引和下一个索引。获取结果时,我们锁定访问以确保我们以原始方式更改它们的顺序,然后返回对象。我们在写出命中数时也会作弊;我们知道最受欢迎的是什么,然后我们可以向后遍历该集合-甚至实际上提取List的键,对其进行排序并对其进行迭代。publicclassPopularityContest{privateDictionary>PopularityContainer{get;放;}privateDictionaryResultContainer{get;放;}privateintMaxPopularity=0;publicPopularityContest(){PopularityContainer=newDictionary>();ResultContainer=newDictionary();}私有对象_SyncLock=新对象();publicResultGetResult(stringresultKey){结果结果=ResultContainer[resultKey];锁(_SyncLock){intcurrentHits=result.Hits;如果(PopularityContainer.ContainsKey(currentHits)&&PopularityContainer[currentHits].Contains(result)){PopularityContainer[currentHits].Remove(result);}if(!PopularityContainer.ContainsKey(currentHits+1)){PopularityContainer.Add(currentHits+1,newList());}PopularityContainer[currentHits+1].Add(Result);if((currentHits+1)>MaxPopularity){MaxPopularity=currentHits+1;}}返回结果;}publicvoidWritePopularity(){//这里也可以将键提取到列表中,对其进行排序,然后w说吧。//注意,因为这是一个读操作,依赖于顺序,你也可以考虑在这里加锁。for(inti=MaxPopularity;i>=0;i--){if(PopularityContainer.Contains(i)&&PopularityContainer[i].Count>0){//注意key[i]处的项目顺序是他们获得受欢迎程度的顺序下面的缓存公开了一个简单的Add/Get接口,用于在缓存中添加和检索项目,这显然可以通过实现IEnumerable来改进,IEnumerable通过缓存枚举所需的行为。这里显然有一个线程问题需要解决。publicclassCache:IEnumerable{//保存缓存值的字典privateDictionarym_cacheStore=newDictionary();//保存每个键被访问次数的字典privateDictionarym_cacheAccessCount=newDictionary();publicTGet(stringcacheKey){if(m_cacheStore.ContainsKey(cacheKey)){//增加访问计数器if(!m_cacheAccessCount.ContainsKey(cacheKey))m_cacheAccessCount.Add(cacheKey,0);m_cacheAccessCount[cacheKey]=m_cacheAccessCount[cacheKey]+1;返回m_cacheStore[cacheKey];}抛出新的KeyNotFoundException(cacheKey);}publicintGetHits(stringcacheKey){returnm_cacheAccessCount.ContainsKey(cacheKey)?m_cacheAccessCount[缓存键]:0;}publicvoidAdd(stringcacheKey,TcacheValue){if(m_cacheStore.ContainsKey(cacheKey))thrownewArgumentException(string.Format("具有键{0}的元素已存在于缓存中",cacheKey));m_cacheStore.Add(cacheKey,cacheValue);}#地区IEnumerable的实现publicIEnumeratorGetEnumerator(){foreach(varsourceinm_cacheAccessCount.OrderBy(kvp=>kvp.Value)){yieldreturnm_cacheStore[source.Key];}}IEnumeratorIEnumerator.GetEnumerator(){返回GetEnumerator();}#endregion}“正确”的方法是在MyCache类中实现IComparable(http://msdn.microsoft.com/en-us/library/system.icomparable.aspx)接口这将公开一个名为CompareTo的方法,您必须在代码中编写该方法。您只需创建该方法并在其中放置一些逻辑,说明该对象是否大于、小于或等于传入的对象。然后通过说intresult=MyCache1.ComparTo(MyCache2);在客户端代码中使用它。intresult=MyCache1.ComparTo(MyCache2);结果将是-10或1,具体取决于它是大于小于还是等于。那这个呢:varMyCache=newSortedDictionary();MyCache['我的结果2']=(MyCache['我的结果2']??0)+1;你想要这样的东西吗?publicclassResult{publicintHits=0;公共字符串名称=“”;publicvoidIncreaseHits(){this.hits++;}publicResult(Stringname){this.name=name;}}classProgram{publicDictionaryMyCache;//使用什么结构?publicmain(){MyCache.Add("我的结果1",newResult("我的结果1"));MyCache.Add("我的结果2",newResult("我的结果2"));MyCache.Add("我的结果3",newResult("我的结果3"));MyCache["我的结果2"].IncreaseHits();MyCache["我的结果2"].IncreaseHits();MyCache["我的结果3"].IncreaseHits();foreach(结果结果在MyCache.Values.OrderByDesc(x=>x.Hits)){Console.Write(result.Name+"-hits"+result.Hits);}}}其他publicclassMyCacheClass{privateDictionarycache=newDictionary();publicvoidIncreaseHits(stringname){结果缓存;if(!cache.TryGetValue(name,outcached)){缓存d=cache.Add(新结果(名称));}缓存。IncreaseHits();}publicstringAdd(stringname){//需要阻止重复....cache.Add(name,newResult(name));}publicIEnumerableSortDesc{get{returncache.Values.OrderByDesc(x=>x.Hits);}}}类程序{MyCacheClassMyCache=newMyCacheClass();MyCache.Add("result1");("我的结果2");MyCache.IncreaseHits("我的结果2");MyCache.IncreaseHits("我的结果3");foreach(ResultresultinMyCache.SorDesc){Console.WriteLine(string.Format("{0}-hits{1}",result.Name,result.Hits);}}为什么不使用经典列表并使用排序方法并编写自己的比较delagate?MyCache.Sort(delegate(Resulta,Resultb){if(a.hits>b.hits)return-1;if(a.hits如果需要,你可以有2个结构按键访问一个用于快速访问,另一个用于保存排序数据。以上就是C#学习教程:C#按值对象排序列表。如果对你有用,需要进一步了解C#学习教程,希望大家多多分享关注---字典accessMap;列出我的缓存;accessMap["对象1"]=obj1;MyCache.add(obj1);accessMap[对象1].Increase();//sortMyCacheforeach(ResultresultinMyCache){Console.Write(result.Name+"-hits"+result.Hits);}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: