使用SelectMany()的不同方法

Ali*_*ini 13 c# linq

我想知道如何使用SelectMany().它似乎需要这么多论点,而且从我自己的推算中我注意到它selectmany可能是所有其他选择操作的"父亲".

Rei*_*ica 31

选择多个允许您从查询源中选择属性是IEnumerable <T>集合,但不是返回集合集合(IEnumerable <IEnumerable <T >>),它会将集合展平为单个集合.

这是一个示例,您可以运行以演示Select和SelectMany之间的差异:

//set up some data for our example
var tuple1 = new { Name = "Tuple1", Values = new int [] { 1, 2, 3 } };
var tuple2 = new { Name = "Tuple2", Values = new int [] { 4, 5, 6 } };
var tuple3 = new { Name = "Tuple3", Values = new int [] { 7, 8, 9 } };

//put the tuples into a collection
var tuples = new [] { tuple1, tuple2, tuple3 };

//"tupleValues" is an IEnumerable<IEnumerable<int>> that contains { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }
var tupleValues = tuples.Select(t => t.Values);

//"tupleSelectManyValues" is an IEnumerable<int> that contains { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
var tupleSelectManyValues = tuples.SelectMany(t => t.Values);
Run Code Online (Sandbox Code Playgroud)

通过使用SelectMany,您可以更轻松地查询子集合中的值.


rol*_*and 13

有几个重载SelectMany.其中一个允许您在遍历层次结构时跟踪父级和子级之间的任何关系.

示例:假设您具有以下结构:League -> Teams -> Player

您可以轻松返回平坦的球员集合.但是,您可能会失去对玩家所属团队的任何引用.

幸运的是,出于此目的存在过载:

var teamsAndTheirLeagues = 
         from helper in leagues.SelectMany
               ( l => l.Teams
                 , ( league, team ) => new { league, team } )
                      where helper.team.Players.Count > 2 
                           && helper.league.Teams.Count < 10
                           select new 
                                  { LeagueID = helper.league.ID
                                    , Team = helper.team 
                                   };
Run Code Online (Sandbox Code Playgroud)

前面的例子来自Dan的IK博客:

http://blogs.interknowlogy.com/2008/10/10/use-linqs-selectmany-method-to-flatten-collections/

强烈建议你看一下.


Dea*_*alk 6

SelectMany基本上可以展平和处理分层数据,并且有两种主要形式

(出于示例的目的,请参阅此初始代码)

class TestObj
{
    public string Name { get; set; }
    public List<string> Items { get; set; }
}

var hierarchicalCollection = new List<TestObj>();

hierarchicalCollection.Add(new TestObj() 
    {Items = new List<string>()
        {"testObj1-Item1", "testObj1-Item2"}, Name="t1"});
hierarchicalCollection.Add(new TestObj() 
    {Items = new List<string>()
        {"testObj2-Item1", "testObj2-Item2"}, Name="t2"});
Run Code Online (Sandbox Code Playgroud)

选项1)从集合集合中创建集合(基本上展平分层数据)

IEnumerable<string> flattenedCollection = 
    hierarchicalCollection.SelectMany(t => t.Items);
Run Code Online (Sandbox Code Playgroud)

结果是:

"testObj1-Item1"
"testObj1-Item2"
"testObj2-Item1"
"testObj2-Item2"
Run Code Online (Sandbox Code Playgroud)

选项2)从集合集合中创建集合,然后通过对原始父集合的引用来处理新集合的每个项目

IEnumerable<string> flattenedModifiedCollection = 
    hierarchicalCollection.SelectMany
        (t => t.Items, (t, i) => t.Name + " : " + i);
Run Code Online (Sandbox Code Playgroud)

结果是:

"t1 : testObj1-Item1"
"t1 : testObj1-Item2"
"t2 : testObj2-Item1"
"t2 : testObj2-Item2"
Run Code Online (Sandbox Code Playgroud)

上述每个用途都有一个变体,其中正在处理的项目的索引可用于转换功能.