【问题标题】:Query a dictionary to get top 3 most common elements查询字典以获取前 3 个最常见的元素
【发布时间】:2019-09-27 16:17:24
【问题描述】:

所以我有一个 IEnumerable CallsForProperty 我需要找到特定时间段的前 3 个问题,所以我创建了 3 个字典

 Dictionary<int, string> FAQfor3Months = null;
 Dictionary<int, string> FAQfor4to12Months = null;
 Dictionary<int, string> FAQfor12plusMonths = null;

 foreach(Activity call in CallsForProperty){
   if( /*call is in 3 months*/ ){
      //do some unrelated stuff
      FAQfor3Months.Add(counter, call.callQuestion)
      counter++;
   }
 }

我有两个问题,

我正在尝试获取前 3 个最常见的问题,这个查询对吗?

var threeMonthFaqs = FAQfor3Months.GroupBy(x => x.Value).OrderByDescending(x => x.Count()).Take(3);   

这也是低效的吗?有没有更好的方法来查询集合?

【问题讨论】:

  • 有点难以辨别你到底想在这里做什么。这还引发了许多其他问题;例如,如果您有一个后备数据存储,您通常希望尝试直接对数据库执行此查询,而不是将所有数据加载到内存中。另外,您能否提供一些关于您希望这些字典包含什么内容的 cmets?您确定(在您的方法中)您不想要 Dictionary,其中 Key 是问题,Value 是问题被问到的次数?
  • 你所做的绝对是你所要求的倒退。您不需要Dictionary 来存储问题,您可以只使用List&lt;string&gt; 然后查询,但它会比Dictionary 更有效,并在遇到问题时增加计数(即GroupBy+Count 以后基本上会做什么)。此外,将变量初始化为 null 将不允许您使用它们。
  • 是的,我想我试图缩短它太多,字典被填充了一个计数器作为索引和字符串问题作为值。我需要在特定时间范围内最常见的 3 个问题,所以我在每个时间范围内都制作了一本字典。
  • @Neovssmith 不,我明白你的代码在做什么,这只是完成你想要的事情的一种糟糕方式......Dictionary 对你没有任何帮助。

标签: c# linq dictionary


【解决方案1】:

反转Dictionarys 并计算遇到的每个问题,然后您可以使用 LINQ 提取前 3 个问题:

var FAQfor3Months = new Dictionary<string, int>();
var FAQfor4to12Months = new Dictionary<string, int>();
var FAQfor12plusMonths = new Dictionary<string, int>();

foreach (Activity call in CallsForProperty) {
    if ( /*call is in 3 months*/ ) {
        //do some unrelated stuff
        FAQfor3Months.TryGetValue(call.callQuestion, out int count);
        FAQfor3Months[call.callQuestion] = count+1;
    }
}

var top3ThreeMonthFaqs = FAQfor3Months.OrderByDescending(kvp => kvp.Value).Take(3).Select(kvp => kvp.Key).ToList();

【讨论】:

  • 我认为我对问题的解释很差/缩短了,stackoverflow 不会让我删除它。 .可以有多个相同的问题,因此它们不能用作键。我需要知道这个问题被问了多少次。
  • @Neovssmith 但这不正是它们应该用作键的原因吗?您想将相同的问题组合起来并计算它们出现的次数吗?否则GroupBy 将无法工作...
  • 哦,我认为你是对的,我认为这是一种更好的方法。让我试着把它连接起来
  • @Neovssmith 注意:您可以通过使用一种特殊的数据结构来提高效率,该结构保留值的索引并仅在添加或更改时排序,但除非您有数以万计的问题,否则它不会不值得。
【解决方案2】:

您的代码将返回组,而不是实际问题。 试试这个:

var threeMonthFaqs = FAQfor3Months.Values
                                  .GroupBy(q => q)
                                  .OrderByDescending(g => g.Count())
                                  .SelectMany(g => g)
                                  .Distinct()
                                  .Take(3);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-11
    • 2022-01-18
    • 2010-11-04
    • 2021-04-10
    • 2013-06-03
    • 2023-04-10
    • 2017-07-30
    相关资源
    最近更新 更多