Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.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#_Linq - Fatal编程技术网

如何使用C#从列表中选择随机对象?

如何使用C#从列表中选择随机对象?,c#,linq,C#,Linq,我有一个IQueryable包含300多个对象: public class Detail { public int Id { get; set; } public int CityId { get; set; } public bool Chosen { get; set; } } IQueryable<Detail> details = ... 公共类详细信息 { 公共int Id{get;set;} public int CityId{get;set;

我有一个IQueryable包含300多个对象:

public class Detail
{
    public int Id { get; set; }
    public int CityId { get; set; }
    public bool Chosen { get; set; }
}

IQueryable<Detail> details = ...
公共类详细信息
{
公共int Id{get;set;}
public int CityId{get;set;}
已选择公共布尔值{get;set;}
}
IQueryable详细信息=。。。

我怎样才能反对这一点,随机挑选50个对象?我假设我需要用.ToList()转换它,但我不确定如何挑选随机元素

300不是很多,所以是的,列个清单:

IQueryable<Detail> details = ...
IList<Detail> detailList = details.ToList();
你可以重复50次。然而,这将导致重复,消除重复的过程将变得混乱

因此,使用a,然后选择前50个:

Shuffle(detailList);
var selection = detailList.Take(50);

这将避免重复。

如果您事先知道要从中随机选取的项目总数,则无需先转换为列表即可

以下方法将为您完成此操作:

/// <summary>Randomly selects items from a sequence.</summary>
/// <typeparam name="T">The type of the items in the sequence.</typeparam>
/// <param name="sequence">The sequence from which to randomly select items.</param>
/// <param name="count">The number of items to randomly select from the sequence.</param>
/// <param name="sequenceLength">The number of items in the sequence among which to randomly select.</param>
/// <param name="rng">The random number generator to use.</param>
/// <returns>A sequence of randomly selected items.</returns>
/// <remarks>This is an O(N) algorithm (N is the sequence length).</remarks>

public static IEnumerable<T> RandomlySelectedItems<T>(IEnumerable<T> sequence, int count, int sequenceLength, System.Random rng)
{
    if (sequence == null)
    {
        throw new ArgumentNullException("sequence");
    }

    if (count < 0 || count > sequenceLength)
    {
        throw new ArgumentOutOfRangeException("count", count, "count must be between 0 and sequenceLength");
    }

    if (rng == null)
    {
        throw new ArgumentNullException("rng");
    }

    int available = sequenceLength;
    int remaining = count;
    var iterator  = sequence.GetEnumerator();

    for (int current = 0; current < sequenceLength; ++current)
    {
        iterator.MoveNext();

        if (rng.NextDouble() < remaining/(double)available)
        {
            yield return iterator.Current;
            --remaining;
        }

        --available;
    }
}
Random rnd=new Random();
IQueryable details=myList.OrderBy(x=>rnd.Next()).Take(50);
var l=new List();
l、 添加(“A”);
l、 添加(“B”);
l、 添加(“C”);
l、 添加(“D”);
l、 添加(“E”);
l、 添加(“F”);
l、 添加(“G”);
l、 添加(“H”);
l、 添加(“I”);
var random=新的random();
var nl=l.Select(i=>new{Value=i,Index=random.Next()});
var finalList=nl.OrderBy(i=>i.Index).Take(3);
foreach(finalList中的var i)
{
控制台写入线(即值);
}

这就是我最终的工作方式,它确保不会返回重复的内容:

public List<T> GetRandomItems(List<T> items, int count = 3)
{
    var length = items.Count();
    var list = new List<T>();
    var rnd = new Random();
    var seed = 0;

    while (list.Count() < count)
    {
        seed = rnd.Next(0, length);
        if(!list.Contains(items[seed]))
            list.Add(items[seed]);
    }

    return list;
}
公共列表GetRandomItems(列表项,整数计数=3) { var length=items.Count(); var list=新列表(); var rnd=新随机数(); var-seed=0; while(list.Count()这个问题的可能重复并没有涉及挑选50个项目。那么它可能是一个重复,但我不确定如何挑选随机项目,这就是我提出这个问题的原因。多有趣的洗牌算法。我总是不断迭代,直到得到50个唯一项,但这显然是一个更糟糕的算法。谢谢你,亨克!是的,
Collections.Shuffle
,您需要链接到该算法或将您的算法放在内联中。@neoistheone:heh,与Java库混淆了。亨克已经把算法联系起来了,这就足够了。
Guid
方法绝对是最简单的。你知道,我很好奇,因为当我用谷歌搜索它时,我发现了一个Java库!遗憾的是,它还没有被构建到C#库中。你会认为这是一个相当基本的收集实用程序,我同意你的观点,因为我已经看到了洗牌算法,因为它使这成为一个O(n)操作。我想从技术上讲,你会再重复50次,但如果我记得正确的话,这不会改变符号。我认为这不会使随机项的分布均匀(虽然没有明确说明,但可能可以假设)。要看到这一点,考虑第一个项目,它只能被挑选为第一个随机项目,如果不是,它永远不再是一个候选人。这是一个很好理解的算法。啊,是的。我认为它所比较的随机数只计算了一次(因此,如果它是0.5,它将跳过列表的前半部分),但实际上它每次都会生成一个新的。是的。我现在明白了。
var item1 = details[0];
/// <summary>Randomly selects items from a sequence.</summary>
/// <typeparam name="T">The type of the items in the sequence.</typeparam>
/// <param name="sequence">The sequence from which to randomly select items.</param>
/// <param name="count">The number of items to randomly select from the sequence.</param>
/// <param name="sequenceLength">The number of items in the sequence among which to randomly select.</param>
/// <param name="rng">The random number generator to use.</param>
/// <returns>A sequence of randomly selected items.</returns>
/// <remarks>This is an O(N) algorithm (N is the sequence length).</remarks>

public static IEnumerable<T> RandomlySelectedItems<T>(IEnumerable<T> sequence, int count, int sequenceLength, System.Random rng)
{
    if (sequence == null)
    {
        throw new ArgumentNullException("sequence");
    }

    if (count < 0 || count > sequenceLength)
    {
        throw new ArgumentOutOfRangeException("count", count, "count must be between 0 and sequenceLength");
    }

    if (rng == null)
    {
        throw new ArgumentNullException("rng");
    }

    int available = sequenceLength;
    int remaining = count;
    var iterator  = sequence.GetEnumerator();

    for (int current = 0; current < sequenceLength; ++current)
    {
        iterator.MoveNext();

        if (rng.NextDouble() < remaining/(double)available)
        {
            yield return iterator.Current;
            --remaining;
        }

        --available;
    }
}
// n is the number of items to randomly choose.

public static List<T> RandomlyChooseItems<T>(IEnumerable<T> items, int n, Random rng)
{
    var result = new List<T>(n);
    int index = 0;

    foreach (var item in items)
    {
        if (index < n)
        {
            result.Add(item);
        }
        else
        {
            int r = rng.Next(0, index + 1);

            if (r < n)
                result[r] = item;
        }

        ++index;
    }

    return result;
}
/// <summary>Shuffles the specified array.</summary>
/// <typeparam name="T">The type of the array elements.</typeparam>
/// <param name="array">The array to shuffle.</param>

public void Shuffle<T>(IList<T> array)
{
    for (int n = array.Count; n > 1;)
    {
        int k = _rng.Next(n);
        --n;
        T temp = array[n];
        array[n] = array[k];
        array[k] = temp;
    }
}
Random rnd = new Random();
IQueryable<Detail> details = myList.OrderBy(x => rnd.Next()).Take(50);
var l = new List<string>();
l.Add("A");
l.Add("B");
l.Add("C");
l.Add("D");
l.Add("E");
l.Add("F");
l.Add("G");
l.Add("H");
l.Add("I");

var random = new Random();
var nl = l.Select(i=> new {Value=i,Index = random.Next()});

var finalList = nl.OrderBy(i=>i.Index).Take(3);
foreach(var i in finalList)
{
    Console.WriteLine(i.Value);
}
public List<T> GetRandomItems(List<T> items, int count = 3)
{
    var length = items.Count();
    var list = new List<T>();
    var rnd = new Random();
    var seed = 0;

    while (list.Count() < count)
    {
        seed = rnd.Next(0, length);
        if(!list.Contains(items[seed]))
            list.Add(items[seed]);
    }

    return list;
}