C# - 结合收藏问题

时间:2011-03-27 21:46:27

标签: c# linq collections merge

如果我有IDictionary<int, int>,是否可以收到IEnumerable<int> 将每个KeyValuePair<int, int>反汇编成一个接一个插入的两个(int, int)条目?

小例子:

Dictionary:
5 - 25
6 - 36
7 - 49

Wanted Enumerable:
5, 25, 6, 36, 7, 49

另外,我希望在一个非常漂亮的声明中有这个,但我想不出合适的一个:)


更新

LINQ是否允许每个.Select语句插入多个元素,这些内容可以分享:

xyz.Select(t => (t, null))

这样生成的Enumerable会在它之后包含tnull吗?

6 个答案:

答案 0 :(得分:8)

您可以使用SelectMany<TSource, TResult>(IEnumerable<TSource>, Func<TSource, IEnumerable<TResult>>)(加上重载)。这是一个例子

var dict = new Dictionary<int, int> {
   { 5, 25 },
   { 6, 36 },
   { 7, 49 } 
}; 

var projection = dict.SelectMany(kv => new[] { kv.Key, kv.Value });

根据评论,这只是实现所要求的一种方式。

答案 1 :(得分:4)

您可以创建一个方法,将您的字典按照您想要的方式分解为IEnumerable。

using System.Collections.Generic;
using System;

public class C {

    public static void Main()
    {
        var dic = new Dictionary<int,int>();
        dic[0] = 1;
        dic[2] = 3;
        dic[4] = 5;

        foreach (var i in Decompose(dic))
            Console.WriteLine(i);

        Console.ReadLine();
    }

    public static IEnumerable<int> Decompose(IDictionary<int,int> dic)
    {
        foreach (var i in dic.Keys)
        {
            yield return i;
            yield return dic[i];
        }
    }
}

输出:

  0
  1
  2
  3
  4
  5

答案 2 :(得分:2)

我认为这是

var enumerable = Mix(dict.Keys, dict.Values);

我相信.NET framework 4.0 Enumerable.Zip接近[1]

所以我已经抽出时间来实现这个 MixSequences 方法了,注意我是如何开心的,所以它会结合任意数量的序列(不仅仅是2个)

using System;
using System.Linq;
using System.Collections.Generic;

namespace NS
{
    static class Program
    {
        private static IEnumerable<T> MixSequences<T> (params IEnumerable<T>[] sequences)
        {
            var se = sequences.Select(s => s.GetEnumerator()).ToList();
            try
            {
                while (se.All(e => e.MoveNext()))
                    foreach (var v in se.Select(e => e.Current))
                        yield return v;
            }
            finally
            { se.ForEach(e => e.Dispose()); }
        }

        public static void Main(string[] args)
        {
            var dict = new Dictionary<int,int>{ {1,4},{13,8},{2,1} };
            var twin = new Dictionary<int,int>{ {71,74},{83,78},{72,71} };

            Console.WriteLine("Keys: {0}", string.Join(", ", dict.Keys));
            Console.WriteLine("Values: {0}", string.Join(", ", dict.Values));
            Console.WriteLine("Proof of pudding: {0}", string.Join(", ", MixSequences(dict.Keys, dict.Values)));
            Console.WriteLine("For extra super fun: {0}", string.Join(", ", MixSequences(dict.Keys, twin.Keys, dict.Values, twin.Values)));
        }
    }
}

干杯

[1] 更新有关背景信息,请参阅hereherehere

答案 3 :(得分:1)

尝试使用以下方法:

var list = dictionary.Keys.ToList();
var list2 = dictionary.Values.ToList();

您可以将此列表合并为一个。

答案 4 :(得分:0)

您可以创建一个对象/集合/您使用LINQ的内容。假设您要将两个非常不同/不相关(或几乎不相关)的项合并为一个(伪代码如下):

List<KeyValuePair<string, string>> newList = (from a in AList
                                              select new KeyValuePair<string, string> 
                                              {
                                                a,
                                                getBfromA(a)
                                              });

答案 5 :(得分:0)

  

dict.Select(d =&gt; new [] {d.Key,d.Value})。SelectMany(d =&gt; d)