Concat里面的所有字符串<list <string>&gt;使用LINQ

时间:2015-11-20 20:51:36

标签: c# .net linq

我的问题与此one几乎相同,但List维度为n。 如何使用LINQ连接 List<List<List...<string>> (n维列表)中的所有字符串?

注意:对这两种情况感兴趣, n 已知未知

2 个答案:

答案 0 :(得分:5)

由于链接的问题被标记为c#所以我用c#代码添加了这个答案。

如果已知嵌套列表的数量您必须反复使用SelectMany()将所有嵌套列表展开为字符序列。然后从那个序列中创建字符串。

List<List<List<string>>> nestedList = new List<List<List<string>>>();
var result = new string(nestedList.SelectMany(x => x).SelectMany(x => x).SelectMany(x => x).ToArray());

如果嵌套列表的数量未知,则必须使用反射,因为该类型未知。我没有直接使用反射,但实际上动态类型。当然,这里的表现会很糟糕;)但它会做你想要的。

using Microsoft.CSharp.RuntimeBinder;

//...

private static string ConcatAll<T>(T nestedList) where T : IList
{
    dynamic templist = nestedList;
    try
    {
        while (true)
        {
            List<dynamic> inner = new List<dynamic>(templist).SelectMany<dynamic, dynamic>(x => x).ToList();
            templist = inner;
        }
    }
    catch (RuntimeBinderException)
    {
        List<object> l = templist;
        return l.Aggregate("", (a, b) => a + b);
    }
}

这是测试

private static void Main(string[] args)
{
    List<List<List<string>>> nestedList = new List<List<List<string>>>
    {
        new List<List<string>> {new List<string> {"Hello "}, new List<string> {"World "}},
        new List<List<string>> {new List<string> {"Goodbye "}, new List<string> {"World ", "End "}}
    };

    Console.WriteLine(ConcatAll(nestedList));
}

输出:

Hello World Goodbye World End

<强>更新

稍微摆弄后,我结束了这个实现。也许更好,不试试。

private static string ConcatAll<T>(T nestedList) where T : IList
{
    dynamic templist = nestedList;
    while (templist.Count > 0 && !(templist[0] is char?))
    {
        List<dynamic> inner = new List<dynamic>(templist).SelectMany<dynamic, dynamic>(x =>
        {
            var s = x as string;
            if (s != null)
            {
                return s.Cast<dynamic>();
            }
            return x;
        }).ToList();
        templist = inner;
    }
    return new string(((List<object>) templist).Cast<char>().ToArray());
}

答案 1 :(得分:3)

另一种解决方案可能是使用递归方法来展平所有列表:

 static IEnumerable<string> Flatten(IEnumerable enumerable)
 {
        foreach (object el in enumerable)
        {
            if (enumerable is IEnumerable<string>)
            {
                yield return (string) el;
            }
            else
            {
                IEnumerable candidate = el as IEnumerable;
                if (candidate != null)
                {
                    foreach (string nested in Flatten(candidate))
                    {
                        yield return nested;
                    }
                }
            }
        }
 }

使用此方法,您可以通过这种方式连接所有字符串:

 List<List<List<string>>> nestedList = new List<List<List<string>>>
                                       {
                                          new List<List<string>> {new List<string> {"Hello "}, new List<string> {"World "}},
                                          new List<List<string>> {new List<string> {"Goodbye "}, new List<string> {"World ", "End "}}
                                      };

Console.WriteLine(String.Join(" ",Flatten(nestedList))); 

这个想法取自post