我有一个包含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
&amp;索引3是item no. 72
。如果这是一个正确的解决方案,我将如何在我的卡片上显示它们。
我一直在研究像这些问题Randomize a List<T>&amp; Best way to randomize an array with .NET,但我没有成功。
答案 0 :(得分: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 :(得分: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();
}
答案 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);
}
}