c#, Linq,选择和计数

本文关键字:选择 Linq | 更新日期: 2023-09-27 18:13:49

我正在学习c#。下面的代码输出5。我很困惑Select是如何工作的。结果不应该是2吗,因为序列1中的第二个和第三个单词比序列2中的对应单词短?有人能帮忙解释一下吗?提前感谢!

string[] seq1 = { "jumps", "over", "pop", "milk", "egg", }; 
string[] seq2 = { "jam", "dizzy", "fuzzy", "the" };
var count = seq1.Select( n1 => seq2.Where(n2 => n1.Length < n2.Length) ) .Count();

c#, Linq,选择和计数

你的代码是这样做的:

对于顺序1中的每个项,选择

seq1.Select( n1 => 

序列2小于序列1的元素的集合。

seq2.Where(n2 => n1.Length < n2.Length)

然后计算序列2集合的数量(即5 -每个序列1元素一个)

) .Count();

No。对于seq2.Where(n2 => n1.Length < n2.Length),您筛选比较大小的元素,但是对于seq1.Select(...),您对seq1的每个元素都这样做。这样你就得到了一个列表的列表。Select()函数是一个投影而不是一个过滤器。

在你的例子中,结果如下:'

n1 = "跳转" => [],

n1 = "over" => ["dizzy", "fuzzy"],

n1 = "pop" => ["dizzy", "fuzzy"],

n1 = "milk" => ["dizzy", "fuzzy"],

n1 = "egg" => ["dizzy", "fuzzy"] '

可以看到,您有5个元素,每个元素都包含来自seq2的部分。

首先,Select不像Where那样过滤输入序列。这就是为什么结果是5。数组seq1包含5个单词,您正在从该数组中进行选择。你选择什么并不重要,因为——正如已经说过的——Select不会过滤。

你可以这样写:

int count = seq1
    .Where((n1, index1) => seq2.Length > index1 && n1.Length < seq2[index1].Length)
    .Count();

这里有一个不同的方法,使用Zip + Sum:

int count = seq1.Zip(seq2, (n1, n2) => n1.Length < n2.Length ? 1 : 0).Sum();

计算seq1中的所有元素(所以它就像seq1.Count()

)

这是你的去linq代码:

string[] seq1 = { "jumps", "over", "pop", "milk", "egg", };
string[] seq2 = { "jam", "dizzy", "fuzzy", "the" };
var count = 0;
foreach (string n1 in seq1)
{
    IEnumerable<string> enumerable = seq2.Where(n2 => n1.Length < n2.Length);
    count++;
}

您的代码Selects来自seq2的项目比seq的当前元素短,但对它们不做任何处理。为了实现对"对应"项的比较,您可以运行以下代码段

string[] seq1 = { "jumps", "over", "pop", "milk", "egg", };
string[] seq2 = { "jam", "dizzy", "fuzzy", "the" };
int count = 0;
for (int i = 0; i < Math.Min(seq1.Length,seq2.Length); i++)
{
    if (seq1[i].Length < seq2.Length) count++;
}

它将检查"对应的"项是否在第二个序列中更长

编辑:

更改为SelectMany将使它也遍历seq2

foreach (string n1 in seq1)
    foreach (string s in seq2.Where(n2 => n1.Length < n2.Length))
        count++;