我有这个IEnumerable:
IEnumerable<MyObject>
我需要随机排序MyObject列表。我需要强制转换为ArrayList吗?
或者我可以直接做到吗?感谢
修改
这是我的实际随机顺序函数:
IList<ArchiePacchettoOfferta> list = new List<ArchiePacchettoOfferta>(m_oEnum);
for (int i = 0; i < list.Count; ++i)
{
HttpContext.Current.Response.Write(list[i].Titolo + "<br />");
}
Random rnd = new Random();
for (int i = 0; i < list.Count; ++i)
{
int swapIndex = rnd.Next(i + 1);
ArchiePacchettoOfferta tmp = list[i];
list[i] = list[swapIndex];
list[swapIndex] = tmp;
}
for (int i = 0; i < list.Count; ++i)
{
HttpContext.Current.Response.Write(list[i].Titolo + "<br />");
}
每次都以相同的方式命令列表:(
答案 0 :(得分:6)
IEnumerable<int> ints;
var random = new Random();
var shuffled = ints.OrderBy(i => random.Next()).ToList();
ToList仅用于确保在多次调整迭代时返回相同(随机)顺序。当然,如果你不再需要原版,你可以随便洗牌“
ints = ints.OrderBy(i => random.Next()).ToList();
有一些讨论是否应该仅依赖OrderBy比较元素一次。如果你不想信任你的.NET实现来做到这一点,请拼写出来:
var random = new Random();
var shuffled = ints
.Select(i => new { key=random.Next(), i })
.OrderBy(tmp => tmp.key)
.Select(tmp => tmp.i)
.ToList();
有关此解决的潜在问题的更多背景信息,请参阅以下链接(主要是当前样本的性能下降,以及不均匀分布的风险):
答案 1 :(得分:2)
您不能将IEnumerable<T>
投射到其他类型 - 并且您不会希望转换为非通用{{1无论如何都要输入。
但是,可以做的是将所有内容读入列表(最简单的ArrayList
扩展方法)然后随机播放。 My answer here有一个shuffle代码的例子 - 诚然在迭代器块中,但胆量就在那里。
编辑:如果你每次都看到相同的顺序,我怀疑你在很短的时间内创建了ToList
的多个实例,而且他们都有相同的种子。
阅读this article了解详细信息和解决方法。
答案 2 :(得分:2)
枚举器仅允许“迭代”访问。因此,不可能随机地或以分类的方式访问元素。您必须读取枚举值并(暂时)将它们存储在另一个列表中,您可以为其应用(随机)排序算法。
[edit] 示例:
List<MyObject> list = new List<MyObject>( my_enumerable );
Random rnd = new Random(/* Eventually provide some random seed here. */);
for (int i = list.Count - 1; i > 0; --i)
{
int j = rnd.Next(i + 1);
MyObject tmp = list[i];
list[i] = list[j];
list[j] = tmp;
}
my_enumerable = list;
(我没有测试过示例代码。)