我想创建一个存储在字典中的密钥对列表(顺序并不重要) 结果应类似于适用于数组结构的以下代码:
int[] myArray = new int[] {1,2,3,4,5,6,7,8,9};
List<Tuple<int, int>> list = new List<Tuple<int, int>>();
for (int i = 0; i < myArray.Length; i++)
for (int j = i + 1; j < myArray.Length; j++)
list.Add(new Tuple<int, int>(myArray[i], myArray[j]));
我想到的一件事是使用
创建密钥数组Dictionary.Keys.ToArray()
方法,然后运行两个嵌套循环。 也许还有其他更有效的解决方案?
编辑: 最后的任务是创建一个矩阵,我可以将每个条目与所有其他条目进行比较 字典的值在此任务中并不重要。 我想创建一个包含所有键组合的列表(顺序并不重要)。
有没有更好的方法:
Dictionary<int, object> dict = new Dictionary<int, object>();
dict.Add(1, null);
dict.Add(2, null);
dict.Add(3, null);
dict.Add(4, null);
//...
int[] dictKeys = dict.Keys.ToArray();
List<Tuple<int, int>> list = new List<Tuple<int, int>>();
for (int i = 0; i < dictKeys.Length; i++)
for (int j = i + 1; j < dictKeys.Length; j++)
list.Add(new Tuple<int, int>(dictKeys[i], dictKeys[j]));
答案 0 :(得分:2)
你所拥有的只是产生结果的最简单方法。
虽然可以直接循环字典键,但您应该将它们视为一个数组,以便您可以通过索引轻松访问它们。
但是,在使用之前,您不必创建整个组合矩阵。您可以创建一个枚举器,在循环时创建矩阵:
public static IEnumerable<Tuple<int, int>> Combinations(IEnumerable<int> keys) {
int[] a = keys.ToArray();
for (int i = 0; i < a.Length; i++) {
for (int j = i + 1; j < a.Length; j++) {
yield return new Tuple<int, int>(a[i], a[j]);
}
}
}
用法:
foreach (Tuple<int, int> t in Combinations(myDictionary.Keys)) {
// the pair of keys is t.Item1 and t.Item2
}
答案 1 :(得分:0)
也许这个Linq
查询是你想要的:
List<Tuple<int, int>> content = dict.Keys.SelectMany(x =>
dict.Keys, (x, y) => new Tuple<int,int>(x, y)).ToList();
对于带有键1, 2, 3
的字典,它将提供9个元组:
(1,1)(1,2)(1,3)
(2,1)(2,2)(2,3)
(3,1)(3,2)(3,3)
答案 2 :(得分:0)
您可以使用生成笛卡尔积的方法:
public static class EnumerableExtensions
{
public static IEnumerable<TResult> Cartesian<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 from item1 in first
from item2 in second
select resultSelector(item1, item2);
}
}
然后在你的钥匙上消费它:
IEnumerable<int> firstKeySet = dict.Keys;
IEnumerable<int> secondKeySet = dict.Keys;
IEnumerable<KeyValuePair<int, int>> cartasian = firstKeySet
.Cartesian(secondKeySet,
(k, v) =>
new KeyValuePair<int, int>
(k, v));
您可以在MoreLINQ内找到此内容以及更多内容。
答案 3 :(得分:0)
我会使用以下方法:
int[] myArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var query = from x in Enumerable.Range(0, myArray.Length)
from y in Enumerable.Range(0, myArray.Length)
select new Tuple<int, int>(x, y);
foreach (var tupel in query)
{
Console.WriteLine(tupel);
}