为什么SelectMany()没有将string []展平为char []

时间:2014-09-09 07:12:15

标签: c# linq

我只是想了解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(),我知道它会使Collection内的Collection变平,但是在这种情况下它不起作用,这是我写的代码:

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

3 个答案:

答案 0 :(得分:6)

SelectMany签名:

public static IEnumerable<TResult> SelectMany<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TResult>> selector
)

正如您所见SelectManyreffer)期望Func<TSource, IEnumerable<TResult>>作为选择器 - 选择器的返回值必须是IEnumerable实现。在第一种情况下,Select期望任何值(Func<TSource, TResult>):x == "quick"评估 true / false ,因此结果将是可枚举boolIEnumerable<bool>)。不幸的是,bool不能分配给IEnumerable - 这就是它没有编译的原因。

答案 1 :(得分:2)

x == "quick"是一个布尔表达式,因此当您致电s.Select(x => x == "quick")时,它会返回IEnumerable<bool>

出于同样的原因,s.SelectMany(x => x == "quick")将无法编译。因为它需要一个返回IEnumerable<Something>的函数。显然,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

答案 2 :(得分:0)

以下显示了您可以使用 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>的方式。