由于阵中拥有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