我有一个包含两个公共变量的结构。我已经构造了该结构的数组,并希望将其转换为字典。
这是一种完成该任务的方法:
public class TestClass
{
public struct KeyValuePairs
{
public string variableOne;
public float variableTwo
}
private KeyValuePairs[] keyValuePairs;
private Dictionary<string, float> KeyValuePairsToDictionary()
{
Dictionary<string, float> dictionary = new Dictionary<string, float>();
for(int i = 0; i < keyValuePairs.Length; i++)
{
dictionary.Add(keyValuePairs[i].variableOne, keyValuePairs[i].variableTwo);
}
return dictionary;
}
}
现在,它适用于我的特定设置,但是我希望尝试将KeyValuePairsToDictionary()
函数转换为Generic,以便它可以在所有类型上使用。
那么,我的第一个想法就是要做这样的事情:
private Dictionary<T, T> ArrayToDictionary<T>(T[] array)
{
Dictionary<T, T> keyValuePairs = new Dictionary<T, T>();
for(int i = 0; i < array.Length; i++)
{
keyValuePairs.Add(array[i], array[i]); //The problem is right here.
}
return keyValuePairs;
}
您可能会说,我无法访问我试图转换为键值对的任何结构数组的公共字段。
有了这个,您如何建议我进行通用转换?
请注意,我的特定设置要求我将结构转换为字典,因为我正在使用Unity Game Engine。
谢谢。
答案 0 :(得分:5)
在LINQ中已经实现了一种通用的方法。
var dict = myArray.ToDictionary(a => a.TheKey);
随着您的实施
public struct KeyValuePairs
{
public string variableOne;
public float variableTwo;
}
和一个数组
KeyValuePairs[] keyValuePairs = ...;
你得到
Dictionary<string, KeyValuePairs> dict = keyValuePairs
.ToDictionary(a => a.variableOne);
或者
Dictionary<string, float> dict = keyValuePairs
.ToDictionary(a => a.variableOne, a => a.variableTwo);
请注意,第一个变量产生的字典类型为KeyValuePairs
,而第二个变量产生的类型为float
。
根据对话,您似乎对实现此方法很感兴趣。这是一个建议:
public static Dictionary<TKey, TValue> ToDictionary<T, TKey, TValue>(
this IEnumerable<T> source,
Func<T, TKey> getKey,
Func<T, TValue> getValue)
{
var dict = new Dictionary<TKey, TValue>();
foreach (T item in source) {
dict.Add(getKey(item), getValue(item));
}
return dict;
}
或者就是这样,如果您想将项目本身存储为值
public static Dictionary<TKey, T> ToDictionary<T, TKey>(
this IEnumerable<T> source,
Func<T, TKey> getKey
{
var dict = new Dictionary<TKey, T>();
foreach (T item in source) {
dict.Add(getKey(item), item);
}
return dict;
}
答案 1 :(得分:2)
您可以使用Reflection来实现
首先,在变量中添加{get;set;}
,以将其转换为属性
public struct KeyValuePairs
{
public string variableOne { get; set; }
public float variableTwo { get; set; }
}
然后是方法
// T1 -> Type of variableOne
// T2 -> Type of variableTwo
// T3 -> KeyValuesPair type
public static Dictionary<T1, T2> convert<T1,T2,T3>(T3[] data)
{
// Instantiate dictionary to return
Dictionary<T1, T2> dict = new Dictionary<T1, T2>();
// Run through array
for (var i = 0;i < data.Length;i++)
{
// Get 'key' value via Reflection to variableOne
var key = data[i].GetType().GetProperty("variableOne").GetValue(data[i], null);
// Get 'value' value via Reflection to variableTow
var value = data[i].GetType().GetProperty("variableTwo").GetValue(data[i], null);
// Add 'key' and 'value' to dictionary casting to properly type
dict.Add((T1)key, (T2)value);
}
//return dictionary
return dict;
}
我使用以下代码进行测试
KeyValuePairs[] val = new KeyValuePairs[5];
val[0] = new KeyValuePairs() { variableOne = "a", variableTwo = 2.4f };
val[1] = new KeyValuePairs() { variableOne = "b", variableTwo = 3.5f };
val[2] = new KeyValuePairs() { variableOne = "c", variableTwo = 4.6f };
val[3] = new KeyValuePairs() { variableOne = "d", variableTwo = 5.7f };
val[4] = new KeyValuePairs() { variableOne = "e", variableTwo = 6.8f };
Dictionary<string, float> dict = convert<string, float,KeyValuePairs>(val);