首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在C# Zip中组合两个以上的泛型列表?

如何在C# Zip中组合两个以上的泛型列表?
EN

Stack Overflow用户
提问于 2012-04-24 11:40:21
回答 8查看 38K关注 0票数 38

我有三个泛型列表(可能有超过3-4个泛型列表,但在本例中让3)泛型列表。

代码语言:javascript
运行
复制
List<string> list1

List<string> list2

List<string> list3

所有列表都有相同数量的元素(相同的计数)。

我用它将两个列表与ZIP组合在一起:

代码语言:javascript
运行
复制
var result = list1.Zip(list2, (a, b) => new {
  test1 = f,
  test2 = b
}

我将其用于foreach语句,以避免每个列表都使用foreach,如下所示

代码语言:javascript
运行
复制
foreach(var item in result){
Console.WriteLine(item.test1 + " " + item.test2);
}

如何对三个列表使用simmilary和Zip?

谢谢

编辑:

我想要:

代码语言:javascript
运行
复制
List<string> list1 = new List<string>{"test", "otherTest"};

List<string> list2 = new List<string>{"item", "otherItem"};

List<string> list3 = new List<string>{"value", "otherValue"};

在ZIP之后(我不知道方法),我想要结果(在VS2010调试模式下)

代码语言:javascript
运行
复制
[0] { a = {"test"},
      b = {"item"},
      c = {"value"}
    }   

[1] { a = {"otherTest"},
      b = {"otherItem"},
      c = {"otherValue"}
    }  

怎么做?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2012-04-24 11:42:58

对我来说,最明显的方法是使用Zip两次。

例如,

代码语言:javascript
运行
复制
var results = l1.Zip(l2, (x, y) => x + y).Zip(l3, (x, y) => x + y);

将合并(添加)三个List<int>对象的元素。

更新:

您可以定义一个新的扩展方法,它的作用类似于具有三个ZipIEnumerable,如下所示:

代码语言:javascript
运行
复制
public static class MyFunkyExtensions
{
    public static IEnumerable<TResult> ZipThree<T1, T2, T3, TResult>(
        this IEnumerable<T1> source,
        IEnumerable<T2> second,
        IEnumerable<T3> third,
        Func<T1, T2, T3, TResult> func)
    {
        using (var e1 = source.GetEnumerator())
        using (var e2 = second.GetEnumerator())
        using (var e3 = third.GetEnumerator())
        {
            while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext())
                yield return func(e1.Current, e2.Current, e3.Current);
        }
    }
}

现在(在与上面相同的上下文中)的用法变成:

代码语言:javascript
运行
复制
var results = l1.ZipThree(l2, l3, (x, y, z) => x + y + z);

同样,现在可以将您的三个列表与:

代码语言:javascript
运行
复制
var results = list1.ZipThree(list2, list3, (a, b, c) => new { a, b, c });
票数 47
EN

Stack Overflow用户

发布于 2017-08-19 17:19:29

我知道还有一个很有趣的解决方案。这是有趣的,主要从教育的角度来看,但如果一个人需要执行压缩不同数量的清单,那么它也可能是有用的。

此方法将重写.NET的LINQ SelectMany函数,该函数在使用LINQ的查询语法时由约定获得。标准SelectMany实现执行笛卡尔产品。过度的人可以做拉链代替。实际执行可以是:

代码语言:javascript
运行
复制
static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source,
        Func<TSource, IEnumerable<TCollection>> selector, Func<TSource, TCollection, TResult> select)
{
    using (var e1 = source.GetEnumerator())
        using (var e2 = selector(default(TSource)).GetEnumerator())
            while (true)
                if (e1.MoveNext() && e2.MoveNext())
                    yield return select(e1.Current, e2.Current);
                else
                    yield break;
}

它看起来有点吓人,但它是一种压缩逻辑,如果只编写一次,就可以在许多地方使用,客户机的代码看起来也不错--您可以使用标准LINQ查询语法压缩任意数量的IEnumerable<T>

代码语言:javascript
运行
复制
var titles = new string[] { "Analyst", "Consultant", "Supervisor"};
var names = new string[] { "Adam", "Eve", "Michelle" };
var surnames = new string[] { "First", "Second", "Third" };

var results =
    from title in titles
    from name in names
    from surname in surnames
    select $"{ title } { name } { surname }";

如果然后执行:

代码语言:javascript
运行
复制
foreach (var result in results)
    Console.WriteLine(result);

你会得到:

代码语言:javascript
运行
复制
Analyst Adam First
Consultant Eve Second
Supervisor Michelle Third

您应该将这个扩展保持在类中的私有状态,因为否则您将彻底改变周围代码的行为。另外,一个新的类型将是有用的,这样它就不会与IEnumerables的标准LINQ行为相结合。

出于教育目的,我曾经创建过一个小的c#项目,该扩展方法+很少的好处:https://github.com/lukiasz/Zippable

另外,如果您觉得这很有趣,我强烈推荐Jon重新实现LINQ文章

玩得开心!

票数 4
EN

Stack Overflow用户

发布于 2012-04-24 13:21:04

在这种情况下,我们需要决定是否支持具有更好可读性的代码和使用Linq的较短代码,我更喜欢代码可读性。

代码语言:javascript
运行
复制
class Program
{
    static void Main(string[] args)
    {
        List<string> list1 = new List<string> { "test", "otherTest" };
        List<string> list2 = new List<string> { "item", "otherItem" };
        List<string> list3 = new List<string> { "value", "otherValue" };

        var result = CombineListsByLayers(list1, list2, list3);
    }

    public static List<string>[] CombineListsByLayers(params List<string>[] sourceLists)
    {
        var results = new List<string>[sourceLists[0].Count];

        for (var i = 0; i < results.Length; i++)
        {
            results[i] = new List<string>();
            foreach (var sourceList in sourceLists)
                results[i].Add(sourceList[i]);
        }
        return results;
    }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10297124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档