Mam dwa zestawy datariów. Każda z nich jest niezliczona. Chcę dołączyć/połączyć te dwie listy w jedną listę. Jestem pewien, że to jest wykonalne. Nie chcę wykonywać pętli for i zauważyłem, że istnieje metoda unijna i metoda łączenia na dwóch listach. Jakieś pomysły?Dołączanie/łączenie dwóch ciągów IZumerowalnych
Odpowiedz
Zakładając, że twoje obiekty są tego samego typu, możesz użyć albo Union
lub Concat
. Zauważ, że podobnie jak słowo kluczowe SQL UNION
, operacja Union
zapewni wyeliminowanie duplikatów, natomiast Concat
(jak UNION ALL
) po prostu doda drugą listę do końca pierwszej.
IEnumerable<T> first = ...;
IEnumerable<T> second = ...;
IEnumerable<T> combined = first.Concat(second);
lub
IEnumerable<T> combined = first.Union(second);
Jeśli są one z różnych rodzajów, a następnie trzeba będzie Select
nich w coś wspólnego. Np
IEnumerable<TOne> first = ...;
IEnumerable<TTwo> second = ...;
IEnumerable<T> combined = first.Select(f => ConvertToT(f)).Concat(
second.Select(s => ConvertToT(s)));
przypadku ConvertToT(TOne f)
i ConvertToT(TTwo s)
reprezentuje operację, która w jakiś sposób przekształca wystąpienie TOne
(i TTwo
, odpowiednio) do instancji T
.
@Adam ... fantastyczne .... właśnie to, czego potrzebowałem – MikeTWebb
@Adam .... Mówiłem zbyt szybko. Zrobiłem w Unii Dostaję duplikaty rekordów. Czy należy zainicjować kluczową właściwość jakiegoś rodzaju? – MikeTWebb
@MikeTWebb: 'Union' ma przeciążenie, które pozwala ci określić' IEqualityComparer'. –
Po prostu spotkałem się z podobną sytuacją, w której potrzebuję połączyć wiele sekwencji.
Naturalnie szukał istniejących rozwiązań w Google/StackOverflow, jednak nie znalazł niczego, co nie wyliczyło przeliczalnych, np. przekonwertować do tablicy następnie użyć Array.Copy()
itp., więc napisałem rozszerzenie i statyczną metodę utiltiy o nazwie ConcatMultiple
.
Mam nadzieję, że to pomoże każdemu, kto musi zrobić to samo.
/// <summary>
/// Concatenates multiple sequences
/// </summary>
/// <typeparam name="TSource">The type of the elements of the input sequences.</typeparam>
/// <param name="first">The first sequence to concatenate.</param>
/// <param name="source">The other sequences to concatenate.</param>
/// <returns></returns>
public static IEnumerable<TSource> ConcatMultiple<TSource>(this IEnumerable<TSource> first, params IEnumerable<TSource>[] source)
{
if (first == null)
throw new ArgumentNullException("first");
if (source.Any(x => (x == null)))
throw new ArgumentNullException("source");
return ConcatIterator<TSource>(source);
}
private static IEnumerable<TSource> ConcatIterator<TSource>(IEnumerable<TSource> first, params IEnumerable<TSource>[] source)
{
foreach (var iteratorVariable in first)
yield return iteratorVariable;
foreach (var enumerable in source)
{
foreach (var iteratorVariable in enumerable)
yield return iteratorVariable;
}
}
/// <summary>
/// Concatenates multiple sequences
/// </summary>
/// <typeparam name="TSource">The type of the elements of the input sequences.</typeparam>
/// <param name="source">The sequences to concatenate.</param>
/// <returns></returns>
public static IEnumerable<TSource> ConcatMultiple<TSource>(params IEnumerable<TSource>[] source)
{
if (source.Any(x => (x == null)))
throw new ArgumentNullException("source");
return ConcatIterator<TSource>(source);
}
private static IEnumerable<TSource> ConcatIterator<TSource>(params IEnumerable<TSource>[] source)
{
foreach (var enumerable in source)
{
foreach (var iteratorVariable in enumerable)
yield return iteratorVariable;
}
}
Sposób Join jest jak SQL przyłączyć, gdzie liście są Krzyż określany w oparciu o warunek, że nie jest to ciąg konkatenacji lub dodanie do listy. Metoda Union robi to, co chcesz, podobnie jak metoda Concat, ale obie są LAZY ocenia i mają wymaganie, aby parametry miały wartość inną niż null. Zwracają albo ConcatIterator albo UnionIterator i if called repeatedly this could cause problems. Chętna ocena skutkuje odmiennym zachowaniem, jeśli tego właśnie chcesz, można użyć metody rozszerzenia, takiej jak ta poniżej.
public static IEnumerable<T> myEagerConcat<T>(this IEnumerable<T> first,
IEnumerable<T> second)
{
return (first ?? Enumerable.Empty<T>()).Concat(
(second ?? Enumerable.Empty<T>())).ToList();
}
Czy zestawy datariów tego samego typu? Różne rodzaje? – Oded
@Obed .... są tego samego typu. – MikeTWebb