Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C动态字典-从动态对象中选择随机值_C#_Dictionary_Random_Dynamic_Collections - Fatal编程技术网

C# C动态字典-从动态对象中选择随机值

C# C动态字典-从动态对象中选择随机值,c#,dictionary,random,dynamic,collections,C#,Dictionary,Random,Dynamic,Collections,我一直在探索动态字典作为将多个字符串与单个“ID”字符串关联的潜在解决方案。我需要做的是将一系列4个字母的文本字符串分配给一个键,该键也是一个4个字母的文本字符串。每个字符串都是唯一的,范围为AAAA-ZZZZ 键是4个字母的文本字符串,如:AAAA、AAGB等。 每个键可以容纳多个4个字母的文本字符串:ACFE、AAFE等 目标是选择一个关键点,然后随机选择其中一个动态值。我当前的测试设置如下: // Dynamic objects dynamic d1 = new System.Dynami

我一直在探索动态字典作为将多个字符串与单个“ID”字符串关联的潜在解决方案。我需要做的是将一系列4个字母的文本字符串分配给一个键,该键也是一个4个字母的文本字符串。每个字符串都是唯一的,范围为AAAA-ZZZZ

键是4个字母的文本字符串,如:AAAA、AAGB等。 每个键可以容纳多个4个字母的文本字符串:ACFE、AAFE等

目标是选择一个关键点,然后随机选择其中一个动态值。我当前的测试设置如下:

// Dynamic objects
dynamic d1 = new System.Dynamic.ExpandoObject();  
dynamic d2 = new System.Dynamic.ExpandoObject();
dynamic d3 = new System.Dynamic.ExpandoObject();

var dict = new Dictionary<string, dynamic>();

// Assign dynamic objects to the Dictionary Key
dict["AAAA"] = d1;
dict["AAGB"] = d2;
dict["ABDA"] = d3;

// Populate the dynamic object with the value(s)
dict["AAAA"].FooBar = new { i1 = "ACFE", i2 = "AAFE", i3 = "CAED", i4 = "HSGB" };
dict["AAGB"].FooBar = new { i1 = "ZZZZ", i2 = "XXXX", i3 = "CAED", i4 = "HSGB" };
dict["ABDA"].FooBar = new { i1 = "YYYY", i2 = "WWWW", i3 = "CAED", i4 = "HSGB" };

string newName = dict["ABDA"].FooBar.i1;
return newName;

通过正确的字符串。但是有没有一种方法可以设置它,这样我就可以随机抽取其中一个值,而不必显式地指定我要的是哪个值?或者我应该完全改变这种方法吗?我已经使用锯齿状数组做了类似的事情,并将其用作备用方法,但对这个动态字典很好奇,认为它是一种可能的替代方法。

您应该完全改变您的方法。dynamic适用于您对正在处理的对象的形状有所了解的情况,例如,它具有FooBar或i1属性,但您不知道在编译时它将是什么类型,可能来自非类型化语言,如JavaScript或Python


如果您的用例不符合这些标准,我认为您最好使用字典来处理在编译时不知道需要哪部分数据的任何事情,例如,随机抽取值,并对编译时应该知道的形状使用强类类型和接口。

您应该完全改变您的方法。dynamic适用于您对正在处理的对象的形状有所了解的情况,例如,它具有FooBar或i1属性,但您不知道在编译时它将是什么类型,可能来自非类型化语言,如JavaScript或Python


如果您的用例不符合这些标准,我建议您最好在编译时不知道需要哪部分数据的情况下使用字典,例如随机抽取值,并对编译时应该知道的形状使用强类类型和接口。

,假设您已经知道键和值的类型,您可能应该使用字典和可扩展集合作为值。合适的类型是

Dictionary<string, List<string>>

因此,使用dynamic runtime不会带来过多的开销,您可以像从任何集合中一样从列表中随机推送和检索值。

在您的情况下,假设您已经知道键和值的类型,您可能应该使用具有可扩展集合作为值的字典。合适的类型是

Dictionary<string, List<string>>

因此,使用动态运行时不会带来过多的开销,您可以像从任何集合中一样从列表中随机推送和检索值。

使用Base26创建数字

    class Program
    {
        static void Main(string[] args)
        {
            Base26 base26 = new Base26();
            for(int i = 0; i < base26.MAX_NUM; i++) 
            {
                Console.WriteLine(base26.ToString());
            }
            Console.ReadLine();
        }
    }
    public class Base26
    {
        public int MAX_NUM = (int)Math.Pow(26, 4);
        int current = 0;

        public override string ToString()
        {
            byte[] base26 = new byte[4];
            base26[3] = (byte)(current % 26);
            base26[2] = (byte)((current / 26) % 26);
            base26[1] = (byte)((current / (26 * 26)) % 26);
            base26[0] = (byte)((current / (26 * 26 * 26)) % 26);
            current++;
            if (current == MAX_NUM) current = 0;

            return string.Join("", base26.Select(x => (char)(((byte)'A') + x)));
        } 
    }

使用Base26创建数字

    class Program
    {
        static void Main(string[] args)
        {
            Base26 base26 = new Base26();
            for(int i = 0; i < base26.MAX_NUM; i++) 
            {
                Console.WriteLine(base26.ToString());
            }
            Console.ReadLine();
        }
    }
    public class Base26
    {
        public int MAX_NUM = (int)Math.Pow(26, 4);
        int current = 0;

        public override string ToString()
        {
            byte[] base26 = new byte[4];
            base26[3] = (byte)(current % 26);
            base26[2] = (byte)((current / 26) % 26);
            base26[1] = (byte)((current / (26 * 26)) % 26);
            base26[0] = (byte)((current / (26 * 26 * 26)) % 26);
            current++;
            if (current == MAX_NUM) current = 0;

            return string.Join("", base26.Select(x => (char)(((byte)'A') + x)));
        } 
    }

如果您想要一个不可变的集合,则在创建该集合后不会将其添加到该集合中,然后使用查找。如果您需要能够添加/删除条目,请使用字典。我已经包括了一个使用iGroup的示例,但是它是查找最慢的,因为您需要迭代直到找到密钥,但是如果您需要迭代所有密钥,就像您想要为每个密钥提取一个随机字符串一样,它非常有效

以下是使用查找的示例:

var values = new[] {
    new KeyValuePair<string,string> ("AAAA","ACFE"),
    new KeyValuePair<string,string> ("AAAA","AAFE"),
    new KeyValuePair<string,string> ("AAAA","CAED"),
    new KeyValuePair<string,string> ("AAAA","HSGB"),

    new KeyValuePair<string,string> ("AAGB","ZZZZ"),
    new KeyValuePair<string,string> ("AAGB","XXXX"),
    new KeyValuePair<string,string> ("AAGB","CAED"),
    new KeyValuePair<string,string> ("AAGB","HSGB"),

    new KeyValuePair<string,string> ("ABDA","YYYY"),
    new KeyValuePair<string,string> ("ABDA","WWWW"),
    new KeyValuePair<string,string> ("ABDA","CAED"),
    new KeyValuePair<string,string> ("ABDA","HSGB"),
};
// Convert array to a Lookup
var lookup=values.ToLookup(k=>k.Key, v=>v.Value);

// Retrieve random string from entry "AAAA"
var entry = lookup["AAAA"];
var rand = new Random();
var max = entry.Count();
var ans = entry.Skip(rand.Next(max)).First();
下面是一个使用字典的示例:

下面是一个使用iGroup的示例:

var values = new[] {
    new KeyValuePair<string,string> ("AAAA","ACFE"),
    new KeyValuePair<string,string> ("AAAA","AAFE"),
    new KeyValuePair<string,string> ("AAAA","CAED"),
    new KeyValuePair<string,string> ("AAAA","HSGB"),

    new KeyValuePair<string,string> ("AAGB","ZZZZ"),
    new KeyValuePair<string,string> ("AAGB","XXXX"),
    new KeyValuePair<string,string> ("AAGB","CAED"),
    new KeyValuePair<string,string> ("AAGB","HSGB"),

    new KeyValuePair<string,string> ("ABDA","YYYY"),
    new KeyValuePair<string,string> ("ABDA","WWWW"),
    new KeyValuePair<string,string> ("ABDA","CAED"),
    new KeyValuePair<string,string> ("ABDA","HSGB"),
};
//Convert array to IGrouping<string,string>
var group = values.GroupBy(k=>k.Key);

// Retrieve random string from entry "AAAA"
var entry = group.First(k=>k.Key == "AAAA");
var rand = new Random();
var max = entry.Count();
var ans = entry.Skip(rand.Next(max)).First().Value;

如果您想要一个不可变的集合,则在创建该集合后不会将其添加到该集合中,然后使用查找。如果您需要能够添加/删除条目,请使用字典。我已经包括了一个使用iGroup的示例,但是它是查找最慢的,因为您需要迭代直到找到密钥,但是如果您需要迭代所有密钥,就像您想要为每个密钥提取一个随机字符串一样,它非常有效

以下是使用查找的示例:

var values = new[] {
    new KeyValuePair<string,string> ("AAAA","ACFE"),
    new KeyValuePair<string,string> ("AAAA","AAFE"),
    new KeyValuePair<string,string> ("AAAA","CAED"),
    new KeyValuePair<string,string> ("AAAA","HSGB"),

    new KeyValuePair<string,string> ("AAGB","ZZZZ"),
    new KeyValuePair<string,string> ("AAGB","XXXX"),
    new KeyValuePair<string,string> ("AAGB","CAED"),
    new KeyValuePair<string,string> ("AAGB","HSGB"),

    new KeyValuePair<string,string> ("ABDA","YYYY"),
    new KeyValuePair<string,string> ("ABDA","WWWW"),
    new KeyValuePair<string,string> ("ABDA","CAED"),
    new KeyValuePair<string,string> ("ABDA","HSGB"),
};
// Convert array to a Lookup
var lookup=values.ToLookup(k=>k.Key, v=>v.Value);

// Retrieve random string from entry "AAAA"
var entry = lookup["AAAA"];
var rand = new Random();
var max = entry.Count();
var ans = entry.Skip(rand.Next(max)).First();
下面是一个使用字典的示例:

下面是一个使用iGroup的示例:

var values = new[] {
    new KeyValuePair<string,string> ("AAAA","ACFE"),
    new KeyValuePair<string,string> ("AAAA","AAFE"),
    new KeyValuePair<string,string> ("AAAA","CAED"),
    new KeyValuePair<string,string> ("AAAA","HSGB"),

    new KeyValuePair<string,string> ("AAGB","ZZZZ"),
    new KeyValuePair<string,string> ("AAGB","XXXX"),
    new KeyValuePair<string,string> ("AAGB","CAED"),
    new KeyValuePair<string,string> ("AAGB","HSGB"),

    new KeyValuePair<string,string> ("ABDA","YYYY"),
    new KeyValuePair<string,string> ("ABDA","WWWW"),
    new KeyValuePair<string,string> ("ABDA","CAED"),
    new KeyValuePair<string,string> ("ABDA","HSGB"),
};
//Convert array to IGrouping<string,string>
var group = values.GroupBy(k=>k.Key);

// Retrieve random string from entry "AAAA"
var entry = group.First(k=>k.Key == "AAAA");
var rand = new Random();
var max = entry.Count();
var ans = entry.Skip(rand.Next(max)).First().Value;

+…如果数据是不可变的,则可能需要字典或查找。或者甚至是一个iGroup+…如果您的数据是不可变的,您可能需要字典或查找。甚至是一个看起来不错的团体;我将转而使用列表。这似乎是一个很好的方法;我将切换到使用列表。在本例中,一个int就足够了,因为26^4仅为456976。在本例中,一个int就足够了,因为26^4仅为456976。