I have an IEnumerable<T>
and an IEnumerable<U>
that I want merged into an IEnumerable<KeyValuePair<T,U>>
where the indexes of the elements joined together in the KeyValuePair are the same. Note I'm not using IList, so I don't have a count or an index for the items I'm merging. How best can I accomplish this? I would prefer a LINQ answer, but anything that gets the job done in an elegant fashion would work as well.
Note: As of .NET 4.0, the framework includes a .Zip
extension method on IEnumerable, documented here. The following is maintained for posterity and for use in .NET framework version earlier than 4.0.
I use these extension methods:
// From http://community.bartdesmet.net/blogs/bart/archive/2008/11/03/c-4-0-feature-focus-part-3-intermezzo-linq-s-new-zip-operator.aspx
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> func) {
if (first == null)
throw new ArgumentNullException("first");
if (second == null)
throw new ArgumentNullException("second");
if (func == null)
throw new ArgumentNullException("func");
using (var ie1 = first.GetEnumerator())
using (var ie2 = second.GetEnumerator())
while (ie1.MoveNext() && ie2.MoveNext())
yield return func(ie1.Current, ie2.Current);
}
public static IEnumerable<KeyValuePair<T, R>> Zip<T, R>(this IEnumerable<T> first, IEnumerable<R> second) {
return first.Zip(second, (f, s) => new KeyValuePair<T, R>(f, s));
}
EDIT: after the comments I'm obliged to clarify and fix some things:
As a update to anyone stumbling across this question, .Net 4.0 supports this natively as ex from MS:
int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };
var numbersAndWords = numbers.Zip(words, (first, second) => first + " " + second);
Documentation:
The method merges each element of the first sequence with an element that has the same index in the second sequence. If the sequences do not have the same number of elements, the method merges sequences until it reaches the end of one of them. For example, if one sequence has three elements and the other one has four, the result sequence will have only three elements.
Think about what you're asking a bit more closely here:
You want to combine two IEnumerables in which "the indexes of the elements joined together in the KeyValuePair are the same", but you "don't have a count or an index for the items I'm merging".
There's no guarantee your IEnumerables are even sorted or unsorted. There's no correlation between your two IEnumerable objects, so how can you expect to correlate them?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With