C# - combining collections question
If I have a IDictionary<int, int>
, is it possible to receive a IEnumerable<int>
, which
would contain every KeyValuePair<int, int>
disassembled into two (int, int)
entries inserted one after another?
Small example:
Dictionary:
5 - 25
6 - 36
7 - 49
Wanted Enumerable:
5, 25, 6, 36, 7, 49
Also, I wanted to have this in one super-pretty state开发者_Go百科ment, but I couldn't think of an appropriate one :)
Update:
Does LINQ
allow to insert more than one element per .Select
statement, something sharing the idea of:
xyz.Select(t => (t, null))
so that the resulting Enumerable
would contain both t
and null
right after it?
You could use SelectMany<TSource, TResult>(IEnumerable<TSource>, Func<TSource, IEnumerable<TResult>>)
(plus overloads). Here's an example
var dict = new Dictionary<int, int> {
{ 5, 25 },
{ 6, 36 },
{ 7, 49 }
};
var projection = dict.SelectMany(kv => new[] { kv.Key, kv.Value });
As per the comments, this is just one way of achieving what you have asked.
You could create a method that will decompose your dictionary into an IEnumerable in the way you want.
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];
}
}
}
Output:
0
1
2
3
4
5
I'd think of this as
var enumerable = Mix(dict.Keys, dict.Values);
I believe in .NET framework 4.0 Enumerable.Zip comes close[1]
So I've found time to implement thisMixSequences method, Note how just for fun I made it n-ary, so it will combine any number of sequences (not just 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)));
}
}
}
Cheers
[1] Update See here, here or here for background.
try to use following methods:
var list = dictionary.Keys.ToList();
var list2 = dictionary.Values.ToList();
you can join this lists in one.
You can create a object/collection/what have you using LINQ. Say you want to merge two very different/unrelated (or barely related) items into one (pseudo code follows):
List<KeyValuePair<string, string>> newList = (from a in AList
select new KeyValuePair<string, string>
{
a,
getBfromA(a)
});
dict.Select(d => new[] { d.Key, d.Value }).SelectMany(d => d)
精彩评论