简体   繁体   English

创建通用函数以在C#中将数组转换为字典

[英]Creating a Generic Function to convert an Array into a Dictionary in C#

I have a struct which contains two public variables. 我有一个包含两个公共变量的结构。 I have made an array of that struct, and wish to convert it to a Dictionary. 我制作了该结构的数组,并希望将其转换为字典。

Here is one such method of accomplishing that: 这是一种完成该任务的方法:

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;
    }
}

Now, that works for my specific setup, but I wish to try and convert the KeyValuePairsToDictionary() function into a Generic so that it may work across all types. 现在,这适用于我的特定设置,但是我希望尝试将KeyValuePairsToDictionary()函数转换为Generic,以便它可以适用于所有类型。

My first thought, then, was to do something like this: 然后,我的第一个想法就是要做这样的事情:

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;
}

As you can probably tell, I can't access the public fields of whatever struct array I am trying to convert into key-value pairs. 您可能会说,我无法访问我试图转换为键值对的任何结构数组的公共字段。

With that, how would you suggest I go about performing the generic conversion? 这样,您如何建议我进行通用转换?

Please note that my specific setup requires that I convert a struct to a dictionary, for I am using the Unity Game Engine. 请注意,我的特定设置要求我将结构转换为字典,因为我正在使用Unity Game Engine。

Thank you. 谢谢。

A generic way of doing this is already implemented in LINQ. LINQ中已经实现了执行此操作的通用方法。

var dict = myArray.ToDictionary(a => a.TheKey);

With your implementation 随着您的实施

public struct KeyValuePairs
{
    public string variableOne;
    public float variableTwo;
}

and an array 和一个数组

KeyValuePairs[] keyValuePairs = ...;

You get 你得到

Dictionary<string, KeyValuePairs> dict = keyValuePairs
    .ToDictionary(a => a.variableOne);

or alternatively 或者

Dictionary<string, float> dict = keyValuePairs
    .ToDictionary(a => a.variableOne, a => a.variableTwo);

Note that the first variant yields a dictionary with values of type KeyValuePairs , while the second one yields values of type float . 请注意,第一个变体产生具有KeyValuePairs类型值的字典,而第二个变体产生float类型的值。


According to the conversation, it seems that you are interested on how you would implement this. 根据对话,您似乎对如何实现此目标很感兴趣。 Here is a suggestion: 这是一个建议:

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;
}

Or simply like this, if you want to store the item itself as value 或者就是这样,如果您想将项目本身存储为值

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;
}

You can use Reflection to achieve that 您可以使用反射来实现

First of all, add a {get;set;} to the variables to transform them in properties 首先,在变量中添加{get;set;}以将其转换为属性

public struct KeyValuePairs
{
    public string variableOne { get; set; }
    public float variableTwo { get; set; }
}

Then the method 然后的方法

// 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;
}

I used the following code to test 我使用以下代码进行测试

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM