字符串数组中的LINQ"zip"

Kus*_*sek 11 c# linq

假设有两个数组:

String[] title = { "One","Two","three","Four"};
String[] user = { "rob","","john",""};
Run Code Online (Sandbox Code Playgroud)

我需要在user值为Empty 时过滤掉上面的数组,然后将两者连接或压缩.最终输出应该是:

{ "One:rob", "three:john" } 
Run Code Online (Sandbox Code Playgroud)

如何使用LINQ完成?

Jon*_*eet 10

首先,您需要一个Zip操作员将两个阵列压缩在一起.这是Eric Lippert博客的代码的缩写版本(此版本中没有错误检查,仅为了简洁起见):

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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,Zip它将位于.NET 4.0的标准库中.

然后你需要应用一个过滤器和一个投影.所以我们得到:

var results = title.Zip(user, (Title, User) => new { Title, User })
                   .Where(x => x.Title != "")
                   .Select(x => x.Title + ":" + x.User);
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 9

听起来你实际上想要将数据"压缩"在一起(不是连接) - 即成对匹配; 那是对的吗?如果是这样,只需:

    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);
Run Code Online (Sandbox Code Playgroud)

使用此处Zip操作:

// 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);
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,我的目标是让Marc和Jon发布我所拥有的确切答案,以便我不必这样做.节省我的时间.多谢你们! (4认同)

dri*_*iis 6

作为已发布答案的补充,这里是一个不使用Zip方法的解决方案.这假设两个数组的长度相同.

        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);
Run Code Online (Sandbox Code Playgroud)