2017-06-22 94 views
0

我有一個名單與其中72項目。該程序有點像Tinder,其中顯示了圖片和一些文本。隨機化一個列表,但範圍

我想這個List是隨機的,但不是第一個「卡」和最後一個「卡」,例如。 item no. 1 & item no. 72這些必須保留爲第一張和最後一張牌,其餘70個項目將按隨機順序排序。

這裏是我的代碼片段,我定義列表

public class MainPageViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    List<CardStackView.Item> items = new List<CardStackView.Item>(); 
    public List<CardStackView.Item> ItemsList 
    { 
     get { return items; } 
     set { if (items == value) { return; } items = value; OnPropertyChanged(); } 
    } 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if(handler != null) 
     { 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    protected virtual void SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null) 
    { 
     field = value; 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if(handler != null) 
     { 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public MainPageViewModel() 
    { 
     items.Add(new CardStackView.Item() { Name = "xxxx", Photo = new Uri("yyyy"), Description = "zzzz", ID = 1 }); 
     items.Add(new CardStackView.Item() { Name = "xxxx", Photo = new Uri("yyyy"), Description = "zzzz", ID = 2 }); 
     items.Add ........ 
     items.Add(new CardStackView.Item() { Name = "xxxx", Photo = new Uri("yyyy"), Description = "zzzz", ID = 72 }); 
    } 
} 

我能做到這一點,而他們都是在一個列表,或者我應該做一個多維數組。其中索引1是item no. 1,索引2是Randomized List &索引3是item no. 72。如果這是一個適當的解決方案,我將如何去顯示他們在我的卡上。

我一直在看這樣的問題Randomize a List<T> & Best way to randomize an array with .NET,但我沒有成功。

+1

您正在列表爲什麼不使你想洗牌的項目清單,然後shuffle中他們基礎上,回答你已經鏈接到的問題,然後當你完成洗牌後,將靜態項目#1和項目#72添加到適當的位置? – Mashton

+0

@Mashton哦耶爲什麼我沒有想到* facepalm *,我會試試:) – TheGejr

回答

1

這是很容易適應a standard random shuffle algorithm接受起始索引和計數:

public static void Shuffle<T>(IList<T> array, Random rng, int first, int count) 
{ 
    for (int n = count; n > 1;) 
    { 
     int k = rng.Next(n); 
     --n; 
     T temp = array[n+first]; 
     array[n + first] = array[k + first]; 
     array[k + first] = temp; 
    } 
} 

然後,如果你想打亂所有,但第一個和最後一個項目:

Shuffle(items, new Random(), 1, items.Count-2); 
-1

該不該這不是一個大問題,你只需要創建一個只有你想要隨機化的元素的時態列表,然後將它合併回你的原始列表。

下面是一些概念性代碼:

// Randomize elements on a list 
    // within range [firstElement, lastElement] 
    void RandomizeList<T> (List<T> list, int firstElement, int lastElement) 
    { 
     // Array with all elements to be randomized 
     var randomized = new T[lastElement - firstElement]; 

     // Generate random indices 
     // for randomized array 
     var randomIds =new List<int> (UniqueRandom (firstElement, lastElement-1)).ToArray(); 

     // Loop through all elements within the range 
     // and fill list with items in a randomized order 
     for (int i=firstElement; i!=lastElement; i++) 
      randomized[i-firstElement] = list[randomIds[i - firstElement]]; 

     // Loop again to merge random elements into the list 
     for (int i=firstElement; i!=lastElement; i++) 
      list[i] = randomized[i-firstElement]; 
    } 

    /// <summary> 
    /// Returns all numbers, between min and max inclusive, once in a random sequence. 
    /// Original code found in: 
    /// https://stackoverflow.com/a/1011408/6033539 
    /// </summary> 
    IEnumerable<int> UniqueRandom(int minInclusive, int maxInclusive) 
    { 
     List<int> candidates = new List<int>(); 
     for (int i = minInclusive;i <= maxInclusive;i++) 
     { 
      candidates.Add (i); 
     } 
     Random rnd = new Random(); 
     while (candidates.Count > 0) 
     { 
      int index = rnd.Next (candidates.Count); 
      yield return candidates[index]; 
      candidates.RemoveAt (index); 
     } 
    } 
0

試試這個:

private Random random = new Random(); 

public MainPageViewModel() 
{ 
    /* Populate `items` */ 

    items = 
     items 
      .Take(1) 
      .Concat(items.Skip(1).Take(items.Count() - 2).OrderBy(x => random.Next())) 
      .Concat(items.Skip(items.Count() - 1)) 
      .ToList(); 
}