按字段排序列表然后随机排序

时间:2015-06-01 17:29:27

标签: c# linq sorting random

var r = new Random();
var orderedList = aListOfPeople.OrderBy(x => x.Age).ThenBy(x => r.Next());

按“年龄”排序列表然后随机排序更好的方法是什么?

我的目标是确保如果PersonA年龄= PersonB年龄,PersonA将在某些场合出现,PersonB将在其他场合出现。

2 个答案:

答案 0 :(得分:1)

使用SQL中的优秀技术

var orderedList = aListOfPeople.OrderBy(x => x.Age).ThenBy(x => Guid.NewGuid());

答案 1 :(得分:0)

最简单的答案是随机播放然后排序。如果使用稳定排序,则排序必须保留等值键值的随机排序顺序。然而,即使不稳定的排序会扰乱你的洗牌,我也无法想到任何可以解除同等关键值的合理情况。

这可能有点低效,但是......

如果你担心碰撞,我可能会认为你的年龄是几年的整数年龄。在这种情况下,你可以考虑一个基数排序(对于任何活着的人来说256个bin就足够了),当需要将这些垃圾箱重新拼接在一起时,你可以在将它们附加到列表时以随机顺序从每个垃圾箱中删除元素

如果您的列表已经按年龄排序,并且您只想在原地进行随机播放,那么您只需要遍历列表,计算以下多少元素相等,执行这么多元素的就地洗牌,然后前进到下一个不匹配的元素并重复。

后者就是这样的,我想(我会用C语写,因为我不知道C#):

int i = 0;
while (i < a.length) {
  int j;
  while (a[j] == a[i] && j < a.length) j++;
  while (i + 1 < j) {
    int k = random(j - i) + i;
    swap(a[i], a[k]);
    i++;
  }
  i++;
}

Haven没有对它进行测试,但它应该给出粗略的想法。