由於陣中擁有exatly評論隨機值範圍的大小(即20),您將每個數字精確到一次。使用Enumerable.Range
創建每個號碼最簡單,只更改它們出現的順序。
更改順序可以通過OrderBy()
來完成,而隨機在這裏使用。
這是全部基於IEnumerable<T>
。所以它需要被放入一個數組,通過調用ToArray()
來完成。
public int[] RandomlyOrderedValues()
{
Random random = new Random();
return Enumerable.Range(1, 20).OrderBy(x => random.Next()).ToArray();
}
我不是你的老師,但希望你還是自己玩,閱讀文檔,最後用你自己的話說出來。
更改問題,現在隨機範圍大於數組大小。
它總是最好IEnumerable<T>
工作,還有你最有力的工具。
// let's create inifite number of random values:
// note that the Random instance needs to be created only once,
// so it's put into a field.
private Random random = new Random();
public IEnumerable<int> InfiniteRandomValues()
{
while (true)
{
yield return random.Next(1, 100);
}
}
public int[] GetUniqueRandomValues(int numberOfValues)
{
return InfiniteRandomValues()
// only uninque values
.Distinct()
// generate the requested number of distinct values
.Take(numberOfValues)
// put it into an array.
.ToArray();
}
它是如何工作的?當你創建隨機值時,你不知道它會有多少,因爲你不知道它會創建多少重複。無限數量值的生成器肯定有足夠的值。把它想象成一個工廠。只有在迭代IEnumerable
時,纔會創建值。
這被稱爲「延期執行」。只有當您迭代IEnumerable
時,值纔會被源請求。
Distinct
的工作原理是這樣的。它只返回其調用者請求的許多不同的值。
這是Take
。這減少了採取的項目的數量,但仍然不會自行迭代。
ToArray
最終迭代其來源並拉取儘可能多的值。現在向後讀:它取自Take
的所有值,它返回20.自己它從Distinct
取20個值,它迭代它的源直到它有20個不同的值。不同的是從InifiteRandomNumbers
工廠獲得其價值,並且可以根據需要採取儘可能多的措施。
當你終於明白這些東西是如何工作的,你可以非常直觀地使用它。
另外一個更經典的實行
private int[] GetRandomValues()
{
Random random = new Random();
int[] values = new int[20];
for(int i = 0; i < 20; i++)
{
// create random values until you found a distinct oune.
int nextValue;
do
{
nextValue = random.Next(1, 100);
} while (ContainsValue(values, i, nextValue))
values[i] = nextValue;
}
return values;
}
// When adding the values to a List instead of an array, it would be
// much easier, but need copying the vlaues to the array at the end.
// When using the array directly, you have to know which values you
// already generated, because it's initialized with zero.
// This method checks wether the value is in the array within
// the items until endIndex.
private bool ContainsValue(int[] values, int endIndex, int valueToFind)
{
// simple linq way:
// return values.Take(endIndex).Contains(valueToFind);
// classic way:
for(int i = 0; i < endIndex; i++)
{
if (values[i] = valueToFind) return true;
}
return false;
}
使用'HashSet的'而不是int'的'數組,然後做'hashSet.ToArray()' –
dcg
打我給它DCG :)是HashSet的是你最好的選擇,如果你不關心的元素 –
的順序如果它是一所學校的任務是最有可能不夠的,只是使用'HashSet'而是要表明它背後的邏輯。 – Lloyd