[c#] 여러 요소 컬렉션을 결합하는 우아한 방법?

각각 동일한 유형 (예 : List<int> fooList<int> bar)의 개체를 포함하는 임의의 수의 컬렉션이 있다고 가정 해 보겠습니다 . 이러한 컬렉션이 컬렉션에 포함 된 경우 (예 : 유형의 List<List<int>>) SelectMany모든 컬렉션을 하나의 컬렉션으로 결합하는 데 사용할 수 있습니다 .

그러나 이러한 컬렉션이 아직 동일한 컬렉션에없는 경우 다음과 같은 메서드를 작성해야한다는 느낌이 듭니다.

public static IEnumerable<T> Combine<T>(params ICollection<T>[] toCombine)
{
   return toCombine.SelectMany(x => x);
}

나는 다음과 같이 부를 것입니다.

var combined = Combine(foo, bar);

Combine위와 같은 유틸리티 메서드를 작성하지 않고도 (여러 개의) 컬렉션을 결합하는 깨끗하고 우아한 방법이 있습니까? LINQ에서 할 수있는 방법이 있어야 할만큼 간단 해 보이지만 아닐 수도 있습니다.



답변

LINQ를 찾고 .Concat()계십니까?

var combined = foo.Concat(bar).Concat(foobar).Concat(...);

또는 .Union()중복 요소를 제거합니다.


답변

나에게 Concat확장 메서드로서 에게 연결하는 큰 시퀀스가 ​​여러 개있을 때 코드에서 그다지 우아하지 않습니다. 이것은 코드 들여 쓰기 / 서식 문제 일 뿐이며 매우 개인적인 문제입니다.

물론 다음과 같이 보입니다.

var list = list1.Concat(list2).Concat(list3);

다음과 같이 읽을 때 그렇게 읽을 수 없습니다.

var list = list1.Select(x = > x)
   .Concat(list2.Where(x => true)
   .Concat(list3.OrderBy(x => x));

또는 다음과 같은 경우 :

return Normalize(list1, a, b)
    .Concat(Normalize(list2, b, c))
       .Concat(Normalize(list3, c, d));

또는 원하는 형식이 무엇이든. 더 복잡한 연결을 사용하면 상황이 악화됩니다. 나의 이유위의 스타일에 일종의 인지 부조화 는 첫 번째 시퀀스는 Concat방법 외부에 있고 후속 시퀀스는 내부에 있기 때문입니다. 오히려 Concat확장 스타일이 아닌 정적 메서드를 직접 호출하는 것을 선호합니다 .

var list = Enumerable.Concat(list1.Select(x => x),
                             list2.Where(x => true));

더 많은 수의 시퀀스 연결을 위해 OP에서와 동일한 정적 방법을 수행합니다.

public static IEnumerable<T> Concat<T>(params IEnumerable<T>[] sequences)
{
    return sequences.SelectMany(x => x);
}

그래서 다음과 같이 쓸 수 있습니다.

return EnumerableEx.Concat
(
    list1.Select(x = > x),
    list2.Where(x => true),
    list3.OrderBy(x => x)
);

더 좋아 보인다. 내가 작성해야하는 여분의 중복 클래스 이름은 내 시퀀스가 Concat호출로 더 깨끗해 보이는 것을 고려할 때 문제가되지 않습니다 . C # 6 에서는 문제가 적습니다. . 다음과 같이 작성할 수 있습니다.

return Concat(list1.Select(x = > x),
              list2.Where(x => true),
              list3.OrderBy(x => x));

C #에서 다음과 같은 목록 연결 연산자가 있기를 바랍니다.

list1 @ list2 // F#
list1 ++ list2 // Scala

그렇게하면 훨씬 더 깨끗해집니다.


답변

당신이 경우에 즉, 컬렉션의 컬렉션을 가지고 List<List<T>>, Enumerable.Aggregate하나에 모든 목록을 결합하는 더 우아한 방법입니다 :

var combined = lists.Aggregate((acc, list) => { return acc.Concat(list); });


답변

다음 Enumerable.Concat과 같이 사용하십시오 .

var combined = foo.Concat(bar).Concat(baz)....;


답변

사용 Enumerable.Concact:

var query = foo.Concat(bar);


답변

항상 Concat과 결합 된 Aggregate를 사용할 수 있습니다.

        var listOfLists = new List<List<int>>
        {
            new List<int> {1, 2, 3, 4},
            new List<int> {5, 6, 7, 8},
            new List<int> {9, 10}
        };

        IEnumerable<int> combined = new List<int>();
        combined = listOfLists.Aggregate(combined, (current, list) => current.Concat(list)).ToList();


답변

내가 보는 유일한 방법은 Concat()

 var foo = new List<int> { 1, 2, 3 };
 var bar = new List<int> { 4, 5, 6 };
 var tor = new List<int> { 7, 8, 9 };

 var result = foo.Concat(bar).Concat(tor);

그러나 더 나은 것을 결정해야합니다.

var result = Combine(foo, bar, tor);

또는

var result = foo.Concat(bar).Concat(tor);

더 나은 선택 이되는 이유Concat() 중 하나 는 다른 개발자에게 더 분명 할 것이라는 점입니다. 더 읽기 쉽고 간단합니다.