【问题标题】:Can i split a List by element property into smaller lists我可以按元素属性将列表拆分为更小的列表吗
【发布时间】:2021-07-04 04:46:51
【问题描述】:

我有一个庞大的调查答案列表,无论是谁,它们都聚集在一起,我已按回答者的 ID 对列表进行分组,但现在我需要将此列表拆分为较小的列表,其中只有一个人的答案。

我现在的大列表称为“surveyAnswers.Respostas”,每个单独的答案都是“SurveyAnswer”,并且人员 ID 的属性是“quemRespondeu”

我将列表分组如下:“surveyAnswers.Respostas.GroupBy(x => x.quemRespondeu)”

如何创建一个包含来自单个人员 ID 的所有答案的列表??

提前谢谢各位!!

【问题讨论】:

  • 不确定我是否完全理解这个问题,但似乎以下内容应该可以解决问题:surveyAnswers.Respostas.Where(x => x.PersonId == yourSinglePersonId)

标签: c# list group-by split


【解决方案1】:

以下是获取字典的方法,其中键是人员 ID,值是相应人员所有答案的列表:

var grouped = . . .GroupedBy(x => x.quemRespondeu);            //the result you have already

var listByRespondeu = grouped.ToDictionary(g => g.Key, g => g.ToList());    //answers by person id

【讨论】:

    【解决方案2】:

    也许您不需要先进行分组,但我不能保证对抗 Linq 的性能会更好。实际上 Linq 代码更简单,这通常是非常需要的。无论如何,为了完成,假设 quemRespondeu 是 long 类型:

    
    public  Dictionary<long,List<string>> GroupAnswers(List<Answer> AllAnswers)
            {
                long[] allIds = new long[AllAnswers.Count];
                Answer[] AllAnswersArray = AllAnswers.ToArray();
    
                for (int i = 0; i < AllAnswers.Count; i++)
                    allIds[i] = AllAnswers[i].quemRespondeu;
    
                Array.Sort(allIds, AllAnswersArray);
    
                Dictionary<long, List<string>> DictAllAnswersGrouped = new Dictionary<long, List<string>>();
                List<string> ListCurrentUser = null;
    
                long prevId = allIds[0] - 1;//to assure that ListCurrentUser is initialized in the first iteration 
                for (int i=0; i< allIds.Length; i++)
                {
                    long Id = allIds[i];
                    if(Id!=prevId)
                    {
                        ListCurrentUser = new List<string>();
                        DictAllAnswersGrouped.Add(Id, ListCurrentUser);
                        prevId = Id;
                    }
    
                    ListCurrentUser.Add(AllAnswersArray[i].SurveyAnswer);
                }
    
                return DictAllAnswersGrouped;
            }
    
    

    然后你会调用:

      Dictionary<long,List<string>> GroupedAnswersDict = GroupAnswers(surveyAnswers.Respostas);
      
      long user_XId = 10; //whatever you need
      List<string> userX_Answers;
       if (!GroupedAnswersDict.TryGetValue(userX_Id, out userX_Answers))
             userX_Answers = null;
    

    免责声明: 正如我所说,Linq 代码更简单易读,因此在大多数情况下它应该是首选。尽管如此,在某些特定情况下可以选择上面的代码,例如,如果需要一些更复杂的功能,如果 Linq 不能使用,或者它对性能有任何实际好处。

    实际上,出于好奇,我做了一个小测试,看看它的性能如何,并且在没有进一步优化的情况下,Linq 的性能通常优于这个算法(大约 2 倍),甚至将它与完全等效的算法进行比较:

       var grouped = surveyAnswers.Respostas.GroupBy(x => x.quemRespondeu);       
       Dictionary<long, List<string>> GroupedAnswersDict =
                  grouped.ToDictionary(g => g.Key, g => g.Select(l => l.SurveyAnswer).ToList());
    
    

    仅在每个用户的答案数量与用户数量相比非常少的情况下,该算法的性能优于上面的 Linq 代码(小于 1.2 倍),但仍然比分类分组慢(由 Supa 发布在这里,归功于他):

       var grouped = surveyAnswers.Respostas.GroupBy(x => x.quemRespondeu);       
       Dictionary<long, List<Answer>> GroupedAnswersDict = 
                         grouped.ToDictionary(g => g.Key, g => g.ToList());
    

    所以在这种情况下,性能也不是选择它而不是 Linq 的理由。

    【讨论】:

    • 这与上一个答案基本相同,但用几十行代码而不是一行代码:) stackoverflow.com/a/67002410/5714954
    • 当然,我发布了完成代码,也是因为我对性能有疑问。但我刚刚进行了一些测试,Linq 明显优于这段代码,所以我更新了我的答案以明确
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2017-07-30
    • 1970-01-01
    相关资源
    最近更新 更多