Say there are two arrays:
String[] title = { "One","Two","three","Four"};
String[] user = { "rob","","john",""};
I need to filter out the above array when the user
value is Empty then join or zip the two together. Final Output should be like:
{ "One:rob", "three:john" }
How can this be done using LINQ?
For a start, you need a Zip
operator to zip the two arrays together. Here's an abbreviated version of the code from Eric Lippert's blog (no error checking in this version, just for brevity):
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>
(this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> resultSelector)
{
using (IEnumerator<TFirst> e1 = first.GetEnumerator())
using (IEnumerator<TSecond> e2 = second.GetEnumerator())
while (e1.MoveNext() && e2.MoveNext())
yield return resultSelector(e1.Current, e2.Current);
}
Note that Zip
will be in the standard libraries for .NET 4.0.
Then you need to just apply a filter and a projection. So we'd get:
var results = title.Zip(user, (Title, User) => new { Title, User })
.Where(x => x.Title != "")
.Select(x => x.Title + ":" + x.User);
It sounds like you actually want to "zip" the data together (not join) - i.e. match pairwise; is that correct? If so, simply:
var qry = from row in title.Zip(user, (t, u) => new { Title = t, User = u })
where !string.IsNullOrEmpty(row.User)
select row.Title + ":" + row.User;
foreach (string s in qry) Console.WriteLine(s);
using the Zip
operation from here:
// http://blogs.msdn.com/ericlippert/archive/2009/05/07/zip-me-up.aspx
public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>
(this IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> resultSelector)
{
if (first == null) throw new ArgumentNullException("first");
if (second == null) throw new ArgumentNullException("second");
if (resultSelector == null) throw new ArgumentNullException("resultSelector");
return ZipIterator(first, second, resultSelector);
}
private static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult>
(IEnumerable<TFirst> first,
IEnumerable<TSecond> second,
Func<TFirst, TSecond, TResult> resultSelector)
{
using (IEnumerator<TFirst> e1 = first.GetEnumerator())
using (IEnumerator<TSecond> e2 = second.GetEnumerator())
while (e1.MoveNext() && e2.MoveNext())
yield return resultSelector(e1.Current, e2.Current);
}
As a complement to the already posted answers, here is a solution without using the Zip method. This assumes that both arrays is of same length.
var pairs = from idx in Enumerable.Range(0, title.Length)
let pair = new {Title = title[idx], User = user[idx]}
where !String.IsNullOrEmpty(pair.User)
select String.Format("{0}:{1}", pair.Title, pair.User);
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