Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.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#_Hashset - Fatal编程技术网

C# 从哈希集中获取随机元素?

C# 从哈希集中获取随机元素?,c#,hashset,C#,Hashset,我使用下面的代码将我的文本文件加载到hashset HashSet<string> hashs = new HashSet<string>(File.ReadLines("textFile.txt")); HashSet hash=newhashset(File.ReadLines(“textFile.txt”); 我想知道是否有任何简单的方法可以从中获得一条随机线 假设textFile.txt包含10行,我想随机抽取其中一行。您可以生成一个介于0和集合大小之间的随机

我使用下面的代码将我的文本文件加载到hashset

HashSet<string> hashs = new HashSet<string>(File.ReadLines("textFile.txt"));
HashSet hash=newhashset(File.ReadLines(“textFile.txt”);
我想知道是否有任何简单的方法可以从中获得一条随机线


假设textFile.txt包含10行,我想随机抽取其中一行。

您可以生成一个介于0和集合大小之间的随机数,然后在集合中迭代,直到找到索引与生成的数字相同的项。然后选择此项作为随机元素

,或者为任何可枚举项选择更通用的解决方案

public static class RandomExtensions
{
    private static readonly Random rnd = new Random();
    private static readonly object sync = new object();

    public static T RandomElement<T>(this IEnumerable<T> enumerable) {
        if (enumerable == null)
            throw new ArgumentNullException("enumerable");

        var count = enumerable.Count();

        var ndx = 0;
        lock (sync) 
            ndx = rnd.Next(count); // returns non-negative number less than max

        return enumerable.ElementAt(ndx); 
    }
}
公共静态类扩展
{
私有静态只读随机rnd=new Random();
私有静态只读对象同步=新对象();
公共静态T随机化元素(此IEnumerable可枚举){
if(可枚举==null)
抛出新ArgumentNullException(“可枚举”);
var count=enumerable.count();
var-ndx=0;
锁定(同步)
ndx=rnd.Next(count);//返回小于max的非负数
返回可枚举的.ElementAt(ndx);
}
}

无需每次都枚举整个数组,就可以得到一个类似于已接受答案的简单答案:

private static readonly Random     random  = new Random();
private static readonly HashSet<T> hashset = new HashSet<T>();

...

T element = hashset.ElementAt(random.Next(hashset.Count));
private static readonly Random=new Random();
私有静态只读HashSet HashSet=new HashSet();
...
T element=hashset.ElementAt(random.Next(hashset.Count));

自从.Net Framework 3.5以来,您可以使用Linq及其扩展方法。 不指定任何条件作为参数,此方法将返回

序列的第一个元素

你应该考虑使用<代码>枚举.FixStor()/代码>要求你的<代码> HASSETSE/COM>至少包含一个元素。 要检查此前提条件,您可以使用

HashSet.Count
或通过Linq with再次检查,而无需指定条件

HashSet<T> hashSet = new HashSet<T>();

...

if(hashSet.Any())
{
  T randomElement = hashSet.First()
}

如果您计划绘制多个随机值,有效的方法是使用带有整数键的字典来存储信息

HashSet<string> hashs = new HashSet<string>();
Dictionary<int, string> lookup = new Dictionary<int, string>();
foreach (string line in File.ReadLines("textFile.txt")) {
    if (hashs.Add(line)) {
        lookup.Add(lookup.Count, line);
    }
}
        
int randomInt = new Random().Next(lookup.Count);
string randomLine = lookup[randomInt];
HashSet hashs=new HashSet();
字典查找=新建字典();
foreach(File.ReadLines(“textFile.txt”)中的字符串行){
if(哈希添加(行)){
lookup.Add(lookup.Count,行);
}
}
int randomInt=new Random().Next(lookup.Count);
字符串randomLine=查找[randomInt];

(在本例中,您可以使用列表,但使用字典也可以删除单个元素而不影响顺序)。

您尝试了什么?您是否尝试过使用System.Random类生成一个介于0和0之间的随机数,然后按索引引用该项?这些都是MSDN库中已经记录的任务。这个代码看起来怎么样?不知道怎么写:)1。谷歌“系统随机”。2.查看已经提供的文档和代码示例,这些示例可以在web上找到。3.学习,而不是使用复制/粘贴答案。(我想今天是我“急躁”的一天。)
ElementAt
将为空集合抛出异常。@lazyberezovsky如果ElementAt抛出,则RandomElement也应抛出相同的异常。在这种情况下应该有一个RandomElementDefault,ElementAT仍然枚举元素,直到它达到指定的索引,所以它不会更快。如果HashSet元素在多线程环境中更改,则可能返回InvalidOperationException(集合已修改;枚举操作可能无法执行)这可以通过在.ElementAt行上使用锁(对象)或.ToArray()来避免。hashset和store作为新变量将该锁(对象)用于rand Count和.ElementAt,但这可能不是内存效率,而是低效率的性能。并不是说我知道更好的方法,只是说。这将如何返回一个随机项?@derHugo HashSet是一个未排序的结构,所以第一个将是random@orion_tvv我猜每次你调用它时,它仍然会返回相同的元素。。。随机的!=如果您想通过多次调用获得不同的项,则不应使用HashSet,并且必须为转换为类似数组的结构而付费。但对于大多数用例来说,第一项是很好的折衷
T randomElement = hashSet.FirstOrDefault(default(T));
HashSet<string> hashs = new HashSet<string>();
Dictionary<int, string> lookup = new Dictionary<int, string>();
foreach (string line in File.ReadLines("textFile.txt")) {
    if (hashs.Add(line)) {
        lookup.Add(lookup.Count, line);
    }
}
        
int randomInt = new Random().Next(lookup.Count);
string randomLine = lookup[randomInt];