繁体   English   中英

使用LINQ从列表中选择多个对象

[英]Selecting multiple objects from a list using LINQ

我需要从马匹列表中选择随机对象。 目前,我正在尝试使用LINQ。 我需要做的是,用户选择他们想要的对象数量,然后从列表中随机选择该对象数量。

这是我目前的代码:

Random rand = new Random();

//creates a list of horses that haven't yet been assigned to players
List<Horse> unassignedHorses = retrieveUnassignedHorses(); 

List<Horse> selectedHorses = unassignedHorses.OrderBy(m => rand.Next())
    .Take(numberHorses)
    .ToList();

我的问题是这样做的好方法,还是更好的方法。

当您要获取“来自集合的N个随机项目”时,可以使用两种通用方法。

  1. 选择一个随机项目,检查之前是否尚未选择过,如果已经选择过,则选择一个新项目。
  2. 随机整理整个集合,然后获取前N个项目。

您选择第二个选项(尽管您使用的是效率低下且有偏见的方法)。

最好,这取决于。 首先,从技术上讲,第一个选项是O(infinity),因为有可能一遍又一遍地随机选择同一项目。 如果您想谈一谈一般情况,那么它就成为一个有效的选择。

当您想要的项目数仅占集合总大小的一小部分时,第一个选项是最佳选择。 如果您只想获取该系列商品的1%,那么随机选择已选商品的几率非常小。

另一方面,如果您要在集合中占很大比例的项目,则改组是更好的选择,因为您要做的是相同数量的工作,而不管是要一个项目还是全部项目。 如果只需要集合中1%的项目,那么最终将浪费大量您根本不在乎的工作量。

现在,我们真正想要做的是随机地重新整理集合的前N个项目,但不重新整理所有剩余的项目。

有趣的是,这实际上很容易做到。 改组列表的一种更可取的方法是从最高索引倒数到最低索引,选择当前索引以下的项目,然后将其与当前索引交换。 与排序不同,这不会引入偏差,与排序不同的是O(n),它不同于O(n * log(n)),而且更好的是,它很容易停下来 因此,如果我们实现这种改组算法:

public static IEnumerable<T> Shuffle<T>(
    this IEnumerable<T> source, Random random)
{
    var list = source.ToList();
    for (int i = list.Count; i > 0; i--)
    {
        var index = random.Next(i);
        var temp = list[index];
        list[index] = list[i - 1];
        list[i - 1] = temp;
        yield return temp;
    }
}

现在,我们可以将您的解决方案写为:

var selectedHorses = unasignedHorses.Shuffle(rand).Take(numberHorses);
int numberHorses = 3; //or some user input
Random r = new Random();
List<Horse> unassignedHorses = retriveUnassignedHorses();
List<Horse> assignedHorses = new List<Horse>();
do
{
  int rIint = r.Next(0, unnasignedHorses.Count);
  if(!assignedHorses.Contains(unassignedHorses[rInt]))
  {
    assignedHorses.Add(unassignedHorses[rInt]);
  }
} (while assignedHorses.Count != numberHorses);

就像我在评论中说的那样,如果您的方式现在可以工作并且对您有意义,那么为什么要更改它? 我没有尝试过这段代码,但是我认为这样的事情可以满足您的需求。 它似乎过于复杂,但这就是我的解决方案开始的方式,然后我最终简化了它们。

所以你想从列表中选择随机对象

我想这可以做到:

int r = rnd.Next(numberHorses.Count);
Horse  selectedHorse  = unnasignedHorses[r];

暂无
暂无

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

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