【问题标题】:Shuffle List of strings, but not too much随机播放字符串列表,但不要太多
【发布时间】:2017-03-22 10:28:17
【问题描述】:

我有一个 C# 中的字符串列表,例如:

List<string> myList;

假设我通过添加 20 个字符串来填充它,从“1”开始,直到“20”。

myList.Add("1"); // And so on...

我怎样才能以最有效和最优雅的方式随机打乱这个字符串列表,同时限制列表中的每个项目最终从它的原始索引到 4 的距离。

我想要的示例:

我要订单:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

例如,要改组为以下内容:

2 5 4 3 6 1 8 7 10 9 12 11 15 14 13 16 18 15 20 19

一种(直截了当的)方法是将列表分成四个部分,然后分别打乱这些部分。但我仍然不确定这会有多有效。

就我而言,效率意味着不做过于复杂或愚蠢的事情。

【问题讨论】:

  • 你自己有没有尝试过?
  • 为什么要这样做?目的是什么?
  • 您的直接方式比您的规范更具限制性。您的规范允许您的示例以 2 5 4 3 6 ... 开头,但您的直接方式无法生成它。那你想要什么?
  • 你可能想在softwareengineering.stackexchange.com上提问
  • @KrisVandermotten 在引用其他网站时,指出cross-posting is frowned upon 通常会有所帮助

标签: c# list shuffle


【解决方案1】:

以下Linq 将创建一个新索引,其中新索引仅限于远离原始索引的distance 位置

List<string> list = Enumerable.Range(1, 20).Select(i => i.ToString()).ToList();
Random rng = new Random();
int distance = 4;

List<string> newList = list
    .Select((s, i) => 
        new {OrigIndex = i, NewIndex = i + rng.Next(-distance, distance+1), Val = s})
    .OrderBy(a => a.NewIndex).ThenBy(a=>a.OrigIndex)
    .Select(a => a.Val)
    .ToList();  

【讨论】:

  • 非常感谢。这完全符合我所描述的我想要的。
【解决方案2】:

您可以使用以下代码:

List<int> myList = Enumerable.Range(1, 20).ToList(); // Feed the list from 1 to 20

int numberByGroups = 4;
List<int> result = new List<int>();

for (int skip = 0; skip < myList.Count; skip = skip + numberByGroups)
{
    result.AddRange(myList.Skip(skip) // skip the already used numbers
                          .Take(numberByGroups) // create a group
                          .OrderBy(a => Guid.NewGuid()) // "Shuffle"
                          .ToList());
}

Console.WriteLine(String.Join(", ", result));

这将按numberByGroups 组随机播放

【讨论】:

    猜你喜欢
    • 2017-08-16
    • 2020-11-23
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多