【问题标题】:Get list of students whose first name is before their last name alphabetically按字母顺序获取名字在姓氏之前的学生列表
【发布时间】:2015-06-26 19:19:11
【问题描述】:

所以我有一个有名字和姓氏的学生列表。如何以给定的方式使用 LINQ 查询过滤它们:他们的名字按字母顺序排在姓氏之前?

我尝试了一些类似的东西

var newStudents =
        from s in students
        where s.FirstName < s.LastName
        select s;

我在这里面临的问题是无法以这种方式比较字符串。

学生还有一个包含他们成绩的 int 列表,以及另一个查询。我需要提取所有成绩为 2 的学生出现两次。
例如,我需要选择成绩为{ 2, 3, 4, 5, 2 } 的学生,但忽略成绩为{ 2, 3, 4, 5, 6 } 的学生。

【问题讨论】:

  • 我建议查看 LINQ 的 .OrderBy.ThenBy 另外,这是一篇关于 how to sort data 的 MSDN 文章
  • 另外,您的问题几乎是两个独立的问题。我建议删除第二个问题(关于成绩)并在需要时单独询问。它真的与按名称排序然后按另一个名称排序没有任何关系。
  • 对于字符串问题,您可以使用 String.CompareTo() 对字符串排序很有用。 msdn on CompareTo() 如果您可以包含更多围绕您如何存储他们的成绩的代码,那将会很有帮助。
  • 如果您解决了问题,请将其发布为作为答案。不要编辑您的问题。
  • @Darkbound 作为一个单独的问题提出。

标签: c# linq sorting


【解决方案1】:

按字母顺序获取名字在姓氏之前的学生列表

这将过滤掉FirstNameLastName 之前并按FirstName 排序的学生,然后按LastName 排序:

var newStudents = students
    .Where(s => String.Compare(s.FirstName, s.LastName, StringComparison.Ordinal) < 0) // Filter students whose FirstName is before LastName
    .OrderBy(s => s.FirstName) // Order by FirstName
    .ThenBy(s => s.LastName); // If FirstNames are equal, then order by LastName

请注意,我使用的是StringComparison.Ordinal,它区分大小写。您可能想改用StringComparison.OrdinalIgnoreCase

【讨论】:

    【解决方案2】:

    Darkbound 的解决方案:

    var newStudents =
            from s in students
            where s.FirstName.CompareTo(s.LastName) < 0
            select s;
    

    【讨论】:

      【解决方案3】:

      如果您正在使用 Linq to Objects,这将起作用。

      var filteredStudents = 
                  from student in students
                  where String.Compare(s.FirstName, s.LastName, StringComparison.Ordinal) < 0
                  order by student.FirstName, student.LastName
                  select student;
      

      我不知道它是否也适用于 Linq to SQL。

      【讨论】:

        【解决方案4】:

        原来有两个问题(我回滚了问题):

        1)

        如何以给定的方式使用 LINQ 查询过滤它们:它们的第一个 姓名按字母顺序排在姓氏之前?

        2)

        我需要选择一个成绩为{ 2, 3, 4, 5, 2 } 的学生,但忽略一个 成绩为{ 2, 3, 4, 5, 6 }的学生。

        关于问题没有。 1:作为其他成员,我建议使用OrderByThenBy 方法。 至于问题没有。 2:您必须对数据进行分组并获得出现两次的 2 级计数。看一个例子(使用 LinqPad):

        void Main()
        {
            List<Student> stu = new List<Student>(){
                new Student("A", "B", new List<int>{ 2, 3, 4, 5, 2 }),
                new Student("B", "A", new List<int>{ 2, 3, 4, 5, 6 }),
                new Student("B", "A", new List<int>{ 2, 3, 4, 5, 4 })
                };
        
            var qry = stu
                .OrderBy(s=>s.FirstName)
                .ThenBy(s=>s.LastName)
                .Where(s=>s.Grades.GroupBy(r=>r).Any(g=>g.Count(a=>a==2)>1));
            //qry.Dump();
        
        }
        
        // Define other methods and classes here
        public class Student
        {
            public Student(string sFName, string sLName, List<int> grades)
            {
                FirstName = sFName;
                LastName = sLName;
                Grades = grades;
            }
        
            public string FirstName{get;set;}
            public string LastName{get;set;}
            public List<int> Grades{get;set;}
        }
        

        结果:

        FirstName LastName  Grades
        A         B         2 
                            3 
                            4 
                            5 
                            2 
        

        【讨论】:

        • 谢谢,您对我的第二个问题的解决方案确实有效!你能解释一下这行代码.Where(s=&gt;s.Grades.GroupBy(r=&gt;r).Any(g=&gt;g.Count(a=&gt;a==2)&gt;1));
        • 嗯...Where 接受布尔值。因此,首先我按等级对数据进行分组,然后我使用Any 方法为满足标准的每条记录返回布尔值(2 级出现两次)。就是这样。
        猜你喜欢
        • 1970-01-01
        • 2018-02-28
        • 2023-04-03
        • 1970-01-01
        • 1970-01-01
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 2013-01-07
        相关资源
        最近更新 更多