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

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

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

问题

  1. 我是新手程序员,希望你能帮我写出更好的代码。
  2. **描述**
  3. 我想编写一个查询,打印出加利福尼亚州活跃且名字中包含字母RD的人的平均分数。
  4. **示例输入**
  5. StudentName = {"Ben Wild", Score = 65, StudentCity = "CA", StudentActvity= true}
  6. StudentName = {"Sara Ride", Score = 81, StudentCity = "CA", StudentActvity = true}
  7. **我的问题**
  8. 我需要选择他们的姓名和分数,但我不能选择两个Lambda表达式并使用`&&`连接它们。
  9. 我得到了这个错误:`'string'不包含'Score'的定义,也没有可访问的扩展方法'Score'来接受类型为'string'的第一个参数`
  10. 我尝试了很多方法,我将在下面提到我的解决方案:
  11. **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"));

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

}

  1. **第二种方式:**
  2. var studentsName6 = studentList.Where(x => (x.StudentActvity == true) && (x.StudentCity == "CA")).Average(x => x.Score);
  3. List<string> xstudent = new List<string>(studentList.Select(x => x.StudentName));
  4. List<int> intstudent = new List<int>(studentList.Select(x => x.Score));
  5. IEnumerable<string> final = xstudent.Where(
  6. x => x.Contains("R") || x.Contains("r") || x.Contains("d") || x.Contains("D"));
  7. IEnumerable<int> final2 = intstudent;
  8. var convFinal = final.AsQueryable();
  9. var convFinal2 = final2.AsQueryable();
  10. var final3 = studentsName6.AsQueryable().Concat(convFinal.AsQueryable()).Concat(convFinal2);
  11. var final4 = final3.Average(x => x.Score);
  12. 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

  1. StudentName = {&quot;Ben Wild&quot;, Score = 65, StudentCity = &quot;CA&quot;, StudentActvity= true}
  2. 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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace _64_LINQ_Practice
  5. {
  6. class Program
  7. {
  8. static void Main(string[] args)
  9. {
  10. //Access to the class method
  11. var studentList = StudentDatabase.GetStudentsFromDb();
  12. var studentsName6 = studentList.Where(x =&gt; (x.StudentActvity == true) &amp;&amp; (x.StudentCity == &quot;CA&quot;)).Select(x =&gt; x.StudentName);
  13. List&lt;string&gt; xstudent = new List&lt;string&gt;(studentList.Select(x =&gt; x.StudentName));
  14. IEnumerable&lt;string&gt; final = xstudent.Where(
  15. x =&gt; x.Contains(&quot;R&quot;) || x.Contains(&quot;r&quot;) || x.Contains(&quot;d&quot;) || x.Contains(&quot;D&quot;));
  16. foreach (string studentFinal in final)
  17. {
  18. Console.WriteLine(&quot;The students that are active, live in CA and names with r/R or D/d letter :&quot; + studentFinal);
  19. }
  20. }
  21. }
  22. }

and second way:

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

答案1

得分: 0

以下是翻译好的内容:

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

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

  1. var letters = new[] { "r", "d" };
  2. var average = studentList.Where(st =>
  3. st.StudentActvity
  4. && st.StudentCity == "CA"
  5. && letters.Any(l => st.StudentName.Contains(l, StringComparison.OrdinalIgnoreCase))
  6. )
  7. .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.

  1. var letters=new[]{&quot;r&quot;,&quot;d&quot;};
  2. var average=studentList.Where(st=&gt;
  3. st.StudentActvity
  4. &amp;&amp; st.StudentCity == &quot;CA&quot;
  5. &amp;&amp; letters.Any(l=&gt;st.StudentName.Contains(l,StringComparison.OrdinalIgnoreCase))
  6. )
  7. .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:

确定