簡體   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