为什么SelectMany()不将字符串[]展平为字符[]
本文关键字:字符 字符串 SelectMany 为什么 | 更新日期: 2023-09-27 18:21:06
我只是想了解linq是如何工作的,并尝试不同的方法来测试Count()
、GroupBy()
和SelectMany()
。我被困在一个场景中,我不明白为什么SelectMany()
没有将string[]
类型扁平化为char
类型。
这是代码:
string s = "A quick brown fox jumps over the lazy dog".ToLower();
char[] arratchar = s.ToCharArray();
var data= arratchar.GroupBy(x=>x).Select(y=> new {Alphabet = y.Key,Count = y.Count()});
这将完美地返回字符串中的字母计数。
当我这样做时,它会返回a:的计数
string s = "A quick brown fox jumps over the lazy dog".ToLower();
var countofA = s.Count(x => x == 'a');
但现在我正在尝试测试SelectMany()
,我知道它会在集合中压平集合,但在这种情况下它不起作用,下面是我写的代码:
string[] s = "A quick brown fox jumps over the lazy dog".ToLower().Split(' ') ;
var res = s.Select(x => x == "quick"); // this works
var re1s = s.SelectMany(x => x == 'q'); // but this not even compiles
SelectMany
签名:
public static IEnumerable<TResult> SelectMany<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TResult>> selector
)
正如您所看到的,SelectMany
(reffer)期望Func<TSource, IEnumerable<TResult>>
作为选择器——选择器的返回值必须是IEnumerable
实现。在第一种情况下,Select
期望任何值(Func<TSource, TResult>
):x == "quick"
评估值true/false,因此结果将是可枚举的bool
(IEnumerable<bool>
)。不幸的是,bool不可分配给IEnumerable
——这就是它不编译的原因。
x == "quick"
是一个布尔表达式,因此当您调用s.Select(x => x == "quick")
时,它将返回IEnumerable<bool>
出于同样的原因,s.SelectMany(x => x == "quick")
不会编译。因为它需要一个返回CCD_ 22的函数。显然,bool没有实现IEnumerable<T>
,所以它不进行编译。
我相信你对SelectMany
有一些误解。SelectMany用于扁平化某些数据结构。它应该返回IEnumerable<T>
,而不是Boolean
。看看它的签名。
public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector);
它取Func<TSource, IEnumerable<TResult>>
,意味着它取一个以TSource
为参数的函数,并且必须返回IEnumerable<TResult>
。
假设你有List<List<int>>
,它有一些列表,所有列表都包含3个整数。如果您想将List<List<int>>
展平为包含所有9个整数的单个List<int>
,那么您将使用SelectMany
。
List<int> list1 = new List<int> {1, 2, 3};
List<int> list2 = new List<int> { 4, 5, 6 };
List<int> list3 = new List<int> { 7, 8, 9 };
List<List<int>> lists = new List<List<int>>
{
list1,
list2,
list3
};
List<int> flatList = lists.SelectMany(x => x).ToList();
//flatList will contain numbers 1-9
下面展示了使用selectmany可以执行的操作。假设你有一个句子单词列表作为一个字符数组,你想知道使用了什么字符:
List<char[]> sentence = "A quick brown fox jumps over the lazy dog"
.ToLower().Split(' ').Select(o=>o.ToCharArray()).ToList();
List<char> characters = sentence.SelectMany(x => x).ToList();
注意List<char[]>
是如何被平坦化为List<char>
的。