집게사장의 꿈

LINQ SelectMany 시퀀스 평면화 본문

기타/C#

LINQ SelectMany 시퀀스 평면화

Krapboss 2024. 7. 24. 00:16

시퀀스 요소의 IEnumerable 요소를 새로운 형식으로 평면화

public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TCollection,TResult> (
this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,System.Collections.Generic.IEnumerable<TCollection>> collectionSelector, Func<TSource,TCollection,TResult> resultSelector);


반환
IEnumerable<TResult>
해당 요소가 입력 시퀀스의 각 요소에 대해 일대다 변형 함수를 호출한 결과인 IEnumerable<T>입니다.

예외
ArgumentNullException source 또는 selector가 null인 경우

 

this System.Collections.Generic.IEnumerable<TSource> source 참조할 시퀀스 데이터
Func<TSource,System.Collections.Generic.IEnumerable<TCollection>> collectionSelector 시퀀스 요수  TSource를 받아 TSource 의  IEnumerable<TCollection>를 반환하는 컬렉션 셀렉터
Func<TSource,TCollection,TResult> resultSelector TSource에 해당하는 IEnumerable<TCollection>의 각 요소 값 TCollection 값으로 TResult결과값을 반환한다.

 

 

* List 를 평면화 하면서 새로운 형식을 지정하여 반환하

class PetOwner
{
    public string Name { get; set; }
    public List<string> Pets { get; set; }
}

internal class Test // 웰컴 키트 
{
    static void Main(string[] args)
    {
        PetOwner[] petOwners =
       { new PetOwner { Name="Higa",
          Pets = new List<string>{ "Scruffy", "Sam" } },
      new PetOwner { Name="Ashkenazi",
          Pets = new List<string>{ "Walker", "Sugar" } },
      new PetOwner { Name="Price",
          Pets = new List<string>{ "Scratches", "Diesel" } },
      new PetOwner { Name="Hines",
          Pets = new List<string>{ "Dusty" } } };

        // Project the pet owner's name and the pet's name.
        var query =
            petOwners
            .SelectMany(petOwner => petOwner.Pets, // 시퀀스 요소의 Collection 값을 반환한다.
            (petOwner, petName) => new { petOwner, petName }); //각 Collection 요소값을 따로 분리한다.
            //.Where(ownerAndPet => ownerAndPet.petName.StartsWith("S"))
            //.Select(ownerAndPet =>
            //        new
            //        {
            //            Owner = ownerAndPet.petOwner.Name,
            //            Pet = ownerAndPet.petName
            //        }
            //);

        // Print the results.
        foreach (var obj in query)
        {
            Console.WriteLine($"{obj.petOwner.Name} <= {obj.petName}");
        }
    }
}

 

 


 

*새로운 형식을 지정하지 않고, 개체의 IEnumerable 요소를 평면화

public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TResult> (
this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,System.Collections.Generic.IEnumerable<TResult>> selector);

 

this System.Collections.Generic.IEnumerable<TSource> source 시퀀스 요소 데이터
Func<TSource,System.Collections.Generic.IEnumerable<TResult>> selector 참조하는 시퀀스 요소에서 평면화할 시퀀스 요소를 선택

 

 

class PetOwner
{
    public string Name { get; set; }
    public List<string> Pets { get; set; }
}

internal class Test // 웰컴 키트 
{
    static void Main(string[] args)
    {
        PetOwner[] petOwners =
     { new PetOwner { Name="Higa, Sidney",
          Pets = new List<string>{ "Scruffy", "Sam" } },
      new PetOwner { Name="Ashkenazi, Ronen",
          Pets = new List<string>{ "Walker", "Sugar" } },
      new PetOwner { Name="Price, Vernette",
          Pets = new List<string>{ "Scratches", "Diesel" } } };

        // Query using SelectMany().
        IEnumerable<string> query1 = petOwners.SelectMany(petOwner => petOwner.Pets);

        Console.WriteLine("Using SelectMany():");

        //각 List를 평면화 하여 반환한 SelectMany
        foreach (string pet in query1)
        {
            Console.WriteLine(pet);
        }
        IEnumerable<List<String>> query2 =
            petOwners.Select(petOwner => petOwner.Pets);

        Console.WriteLine("\nUsing Select():");

        //각 list를 선택해서 반환한 Select
        foreach (List<String> petList in query2)
        {
            foreach (string pet in petList)
            {
                Console.WriteLine(pet);
            }
            Console.WriteLine();
        }
    }
}

 

 

 


시퀀스 요소의 IEnumerable 요소를 조건을 추가하여 평면화할 수 있는

public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,int,System.Collections.Generic.IEnumerable<TResult>> selector);

 

 

class PetOwner
{
    public string Name { get; set; }
    public List<string> Pets { get; set; }
}

internal class Test // 웰컴 키트 
{
    static void Main(string[] args)
    {
        PetOwner[] petOwners =
     { new PetOwner { Name="Higa, Sidney",
          Pets = new List<string>{ "Scruffy", "Sam" } },
      new PetOwner { Name="Ashkenazi, Ronen",
          Pets = new List<string>{ "Walker", "Sugar" } },
      new PetOwner { Name="Price, Vernette",
          Pets = new List<string>{ "Scratches", "Diesel" } },
      new PetOwner { Name="Hines, Patrick",
          Pets = new List<string>{ "Dusty" } } };

        
        //List 요소를 Select로 하나씩 선택해서 사용
        //First() 함수나 다른 조건을 추가할 수 있다는 장점이 있음
        IEnumerable<string> query =
            petOwners.SelectMany((petOwner, index) =>
                                     petOwner.Pets.Select(pet => index + pet));

        foreach (string pet in query)
        {
            Console.WriteLine(pet);
        }
    }
}

'기타 > C#' 카테고리의 다른 글

2의 보수  (0) 2024.07.31
LINQ 정렬 메서드  (3) 2024.07.24
LINQ 집합  (0) 2024.07.23
LINQ 집계함수  (0) 2024.07.23
LINQ 메서드 GroupBy  (1) 2024.07.23