如何在LINQ方法语法中使用int和string类型交集两个选择?

huangapple go评论63阅读模式
英文:

How to intersect two select with int and string type in LINQ Method syntax?

问题

我是新手程序员,希望你能帮我写出更好的代码。

**描述**

我想编写一个查询,打印出加利福尼亚州活跃且名字中包含字母R或D的人的平均分数。

**示例输入**

    StudentName = {"Ben Wild", Score = 65, StudentCity = "CA", StudentActvity= true}
    
    StudentName = {"Sara Ride", Score = 81, StudentCity = "CA", StudentActvity = true}

**我的问题**

我需要选择他们的姓名和分数,但我不能选择两个Lambda表达式并使用`&&`连接它们。
我得到了这个错误:`'string'不包含'Score'的定义,也没有可访问的扩展方法'Score'来接受类型为'string'的第一个参数`

我尝试了很多方法,我将在下面提到我的解决方案:

**Program.cs 代码**

using System;
using System.Collections.Generic;
using System.Linq;

namespace _64_LINQ_Practice
{
class Program
{
static void Main(string[] args)
{
//访问类方法
var studentList = StudentDatabase.GetStudentsFromDb();
var studentsName6 = studentList.Where(x => (x.StudentActvity == true) && (x.StudentCity == "CA")).Select(x => x.StudentName);
List xstudent = new List(studentList.Select(x => x.StudentName));
IEnumerable final = xstudent.Where(
x => x.Contains("R") || x.Contains("r") || x.Contains("d") || x.Contains("D"));

        foreach (string studentFinal in final)
        {
            Console.WriteLine("活跃,住在CA并且名字中包含r/R或D/d字母的学生:" + studentFinal);
        }
    }
}

}


**第二种方式:**

var studentsName6 = studentList.Where(x => (x.StudentActvity == true) && (x.StudentCity == "CA")).Average(x => x.Score);
List<string> xstudent = new List<string>(studentList.Select(x => x.StudentName));
List<int> intstudent = new List<int>(studentList.Select(x => x.Score));
IEnumerable<string> final = xstudent.Where(
                    x => x.Contains("R") || x.Contains("r") || x.Contains("d") || x.Contains("D"));
IEnumerable<int> final2 = intstudent;
var convFinal = final.AsQueryable();
var convFinal2 = final2.AsQueryable();
var final3 = studentsName6.AsQueryable().Concat(convFinal.AsQueryable()).Concat(convFinal2);
var final4 = final3.Average(x => x.Score);
Console.WriteLine(final4);
英文:

I am new to programming I hope you can help me to write better code.

Description

I want to write a query that prints Average scores of Californians who are active and have the letter R or D in their name.

Example Input

StudentName = {&quot;Ben Wild&quot;, Score = 65, StudentCity = &quot;CA&quot;, StudentActvity= true}

StudentName = {&quot;Sara Ride&quot;, Score = 81, StudentCity = &quot;CA&quot;, StudentActvity = true}

My problem

I need to select their name and their score at the end but I can't select two Lambda expressions and &amp;&amp; them together.
I got this error : &#39;string&#39; does not contain a definition for &#39;Score&#39; and no accessible extension method &#39;Score&#39; accepting a first argument of type &#39;string&#39; could be

I tried so many ways that I will mention my solutions below :

Program.cs code

using System;
using System.Collections.Generic;
using System.Linq;

namespace _64_LINQ_Practice
{
    class Program
    {
        static void Main(string[] args)
        {
            //Access to the class method
            var studentList = StudentDatabase.GetStudentsFromDb();
            var studentsName6 = studentList.Where(x =&gt; (x.StudentActvity == true) &amp;&amp; (x.StudentCity == &quot;CA&quot;)).Select(x =&gt; x.StudentName);
            List&lt;string&gt; xstudent = new List&lt;string&gt;(studentList.Select(x =&gt; x.StudentName));
            IEnumerable&lt;string&gt; final = xstudent.Where(
                                x =&gt; x.Contains(&quot;R&quot;) || x.Contains(&quot;r&quot;) || x.Contains(&quot;d&quot;) || x.Contains(&quot;D&quot;));

            foreach (string studentFinal in final)
            {
                Console.WriteLine(&quot;The students that are active, live in CA and names with r/R or D/d letter :&quot; + studentFinal);
            }
        }
    }
}

and second way:

        var studentsName6 = studentList.Where(x =&gt; (x.StudentActvity == true) &amp;&amp; (x.StudentCity == &quot;CA&quot;)).Average(x =&gt; x.Score);
        List&lt;string&gt; xstudent = new List&lt;string&gt;(studentList.Select(x =&gt; x.StudentName));
        List&lt;int&gt; intstudent = new List&lt;int&gt;(studentList.Select(x =&gt; x.Score));
        IEnumerable&lt;string&gt; final = xstudent.Where(
                            x =&gt; x.Contains(&quot;R&quot;) || x.Contains(&quot;r&quot;) || x.Contains(&quot;d&quot;) || x.Contains(&quot;D&quot;));
        IEnumerable&lt;int&gt; final2 = intstudent;
        var convFinal = final.AsQueryable();
        var convFinal2 = final2.AsQueryable();
        var final3 = studentsName6.AsQueryable().Concat(convFinal.AsQueryable()).Concat(convFinal2);
        var final4 = final3.average(x =&gt; x.Score);
        Console.WriteLine(final4);

答案1

得分: 0

以下是翻译好的内容:

"代码中没有尝试计算平均值,所以不清楚问题出在哪里。根据以下条件,输出学生的平均分数:住在加利福尼亚(CA)且活动为真,名字中包含 R/r 或 D/d 字母的学生的平均分数。

似乎只需要一个 Where 条件来筛选学生,然后使用 Avg 计算平均值。由于不需要计算多个分组的平均值,不需要使用 GroupBy。"

var letters = new[] { "r", "d" };
var average = studentList.Where(st =>
    st.StudentActvity
    && st.StudentCity == "CA"
    && letters.Any(l => st.StudentName.Contains(l, StringComparison.OrdinalIgnoreCase))
)
.Average(st => st.Score);

String.Contains 可以接受一个参数,指定不区分大小写的比较,因此不需要同时指定大小写字母。

letters.Any(l => st.StudentName.Contains(l...)) 检查是否在 StudentName 中包含任何字母。

这个查询将适用于内存数据库和可能是实际数据库。不过,它将非常慢。name.Contains("r") 被转换成 SQL 条件 name LIKE '%r%'。无法使用索引快速查找具有 r 的名字,因此数据库将不得不搜索整个表。

英文:

There's no attempt to calculate averages in the code so it's unclear what the problem is. Going by

> prints the average score of students, with these conditions: Average score of students that live in CA and their activity is true and there are R/r or D/d letters contain in their name.

It seems a single Where is needed to filter the students, then Avg to calculate the average. Since there's no need to calculate averages for multiple groups, GroupBy isn't needed.

var letters=new[]{&quot;r&quot;,&quot;d&quot;};
var average=studentList.Where(st=&gt;
        st.StudentActvity 
        &amp;&amp; st.StudentCity == &quot;CA&quot;
        &amp;&amp; letters.Any(l=&gt;st.StudentName.Contains(l,StringComparison.OrdinalIgnoreCase))
     )
    .Average(st=&gt;st.Score);

String.Contains can accept a parameter that specifies case-insensitive comparison, so there's no need to specify both small and capital letters.

letters.Any(l=&gt;st.StudentName.Contains(l...)) checks if any letter is contained inside StudentName

This query will work with an in-memory database and probably an actual database. It will be very slow though. name.Contains(&quot;r&quot;) is translated to the SQL condition name LIKE &#39;%r%&#39;. There's no way to use an index to quickly find which names have r in their middle, so the database will have to search the entire table

huangapple
  • 本文由 发表于 2023年2月16日 17:28:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75470206.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定