C# 如何从字典内容的特定范围中获取随机值
如果通过这种方式,我可以从给定范围中获得随机值:C# 如何从字典内容的特定范围中获取随机值,c#,dictionary,random,C#,Dictionary,Random,如果通过这种方式,我可以从给定范围中获得随机值: int r = ran.Next(1, 4); string v; if (dict.TryGetValue(r, out v)) { ///... } 如何正确地从特定范围获取词典内容的随机值,例如仅从4到6以及1和2,并避免查找3: Dictionary<int, string> dict = new Dictionary<int, string>() { { 1, "word1" },
int r = ran.Next(1, 4);
string v;
if (dict.TryGetValue(r, out v))
{
///...
}
如何正确地从特定范围获取
词典内容的随机值,例如仅从4到6以及1和2,并避免查找3:
Dictionary<int, string> dict = new Dictionary<int, string>()
{
{ 1, "word1" },
{ 2, "word2" },
{ 3, "word3" },
{ 4, "word4" },
{ 5, "word5" },
{ 6, "word6" }
};
Dictionary dict=new Dictionary()
{
{1,“word1”},
{2,“word2”},
{3,“word3”},
{4,“word4”},
{5,“word5”},
{6,“word6”}
};
下面是一个使用扩展方法的解决方案:
public static class RandomExtensions
{
public static int NextWithinRange(this Random random, params Range[] ranges)
{
if (ranges.Length > 0)
{
Range range = ranges[random.Next(0, ranges.Length)];
return random.Next(range.MinValue, range.MaxValue + 1);
}
return random.Next();
}
public class Range
{
public int MinValue { get; set; }
public int MaxValue { get; set; }
public Range(int minValue, int maxValue)
{
MinValue = minValue;
MaxValue = maxValue;
}
}
}
用法:
int r = ran.NextWithinRange(new Range(1, 2), new Range(4, 6));
string v;
if (dict.TryGetValue(r, out v))
{
///...
}
下面是一个使用LINQ的解决方案:
var rand = new Random();
// create a new dictionary, filtering out any unwanted keys within range(s)
Dictionary<int, string> filteredDict =
dict.Where(pair => (pair.Key >= 1 && pair.Key <= 2)
|| (pair.Key >= 4 && pair.Key <= 6))
.ToDictionary(pair => pair.Key, pair => pair.Value);
// get a random entry from the filtered dictionary
KeyValuePair<int, string> entry = filteredDict.ElementAt(rand.Next(0, filteredDict.Count));
// get random entry's value
string value = entry.Value;
var rand=new Random();
//创建一个新字典,过滤掉范围内所有不需要的键
字典过滤器添加=
dict.Where(pair=>(pair.Key>=1&&pair.Key=4&&pair.Key-pair.Key,pair=>pair.Value);
//从筛选字典中获取随机条目
KeyValuePair entry=Filteredict.ElementAt(rand.Next(0,Filteredict.Count));
//获取随机项的值
字符串值=entry.value;
编辑:感谢@Kyle在我的第一篇博文中指出了潜在的
ArgumentOutOfRange
异常。然后用排除的值创建哈希集
HashSet<int> excludedValues = ....
List<int> values = dict.Where(x=> excludedValues.Contains(x.Key) == false).Select(x=>x.Key).ToList();
int index = rand.Next(1, values.Count);
string value = dict[index];
HashSet excludedvalue=。。。。
List values=dict.Where(x=>excludedValues.Contains(x.Key)==false);
int index=rand.Next(1,value.Count);
字符串值=dict[索引];
通过这种方式,您不限于排除值3。您可以在此集合中放入任何内容。如果集合较大,则应使用比列表快得多的哈希集。通常,在
LINQ
中有两个可用函数,即和
这些函数可用于获取任何IEnumerable
的切片。请记住Dictionary
也是IEnumerable
所以要访问第4个和第10个元素之间的随机元素
var rand = new Random();
dict.Skip(3).Take(6 /* 10 - 4 */).ElementAt(rand.Next(6 /* 10 - 4 */)
现在请记住,序列不一定按键或任何可预测的方式进行排序或排序。您可能必须使用OrderBy
按您选择的顺序遍历字典
如果您想在字典更新期间多次执行这些操作,那么您只需访问
dict.Keys.OrderBy().ToList()
,然后使用相同的Skip().Take().ElementAt()访问此List
或直接使用索引操作。这将避免多次重新枚举同一词典您可以收集所有可以获取的值,然后从中随机选择一个:
private static Random s_Random = new Random();
...
var values = dict
.Where(pair => pair.Key >= 4 && pair.Key <= 6 || // conditions on key
pair.Key >= 1 && pair.Key <= 2)
.ToArray();
var result = values[s_Random.Next(values.Length)];
private static Random s_Random=new Random();
...
var值=dict
其中(pair=>pair.Key>=4&&pair.Key=1&&pair.Key使用此解决方案,您可以在指定范围内获得随机值,而无需首先迭代字典
void Main()
{
Dictionary<int, string> dict = new Dictionary<int, string>()
{
{ 1, "word1" },
{ 2, "word2" },
{ 3, "word3" },
{ 4, "word4" },
{ 5, "word5" },
{ 6, "word6" }
};
var randomizer = new Random();
GetRandomValue(dict, randomizer, new Range(4, 6), new Range(1,2)).Dump();
}
public TValue GetRandomValue<TValue>(IDictionary<int, TValue> dic, Random randomizer, params Range[] ranges)
{
var range = ranges[randomizer.Next(0, ranges.Length)];
var key = randomizer.Next(range.From, range.To + 1);
return dic[key];
}
public class Range
{
public Range(int @from, int to)
{
From = @from;
To = to;
}
public int From {get;set;}
public int To {get;set;}
}
void Main()
{
Dictionary dict=新字典()
{
{1,“word1”},
{2,“word2”},
{3,“word3”},
{4,“word4”},
{5,“word5”},
{6,“word6”}
};
var randomizer=new Random();
GetRandomValue(dict、随机化器、新范围(4,6)、新范围(1,2)).Dump();
}
公共TValue GetRandomValue(IDictionary dic、随机随机化器、参数范围[]范围)
{
var range=范围[randomizer.Next(0,ranges.Length)];
var key=randomizer.Next(range.From,range.To+1);
返回dic[键];
}
公共类范围
{
公共范围(int@from,int-to)
{
From=@From;
To=To;
}
来自{get;set;}的公共int
公共int到{get;set;}
}
根据具体需要,最简单的方法可能是指定可能的数字:
int[] a { 1, 2, 4, 5, 6 };
int r = a[ran.Next(a.Length)];
或
如何保证该范围内的所有值都存在于字典中
如果可以,为什么不使用数组
/列表
来存储它,而不是字典
@Vikhram您好,因为它不是一个更新的列表。是的,对于列表或数组,它是简单而有用的,但我想知道t dictionary如果可能的话。如果dictionary包含排除的键,则该操作可能会失败,因为所选的随机数可能大于剩余的键值对数。这将导致ElementAt
抛出ArgumentOutOfRange
异常。
int r = ran.Next(1, 6);
if (r == 3) r = 6;