消除数组c#中的重复项

时间:2016-11-11 09:01:09

标签: c# arrays

我正在制作一个基本的Deal或No Deal游戏,这样做我必须从阵列中随机挑选10个决赛选手,不需要重复。

我的结构和数组就像这样

public struct People
{
    public string firstname;
    public string lastname;
    public int age;
}

class Program
{
    public static People[] People1 = new People[40];
    public static People[] Finalists1 = new People[10];
    public static People[] Finalist1 = new People[1];

我的决赛选手方法就像这样

Random rand = new Random();

for (int i = 0; i < Finalists1.Length; i++)
{
    num = rand.Next(0, People1.Length);           
    Finalists1[i].lastname = People1[num].lastname;
    Finalists1[i].firstname = People1[num].firstname;
    Finalists1[i].age = People1[num].age;
}

如何在阵列中维护10个人的同时消除重复的条目?

6 个答案:

答案 0 :(得分:5)

由于初始数组不包含重复项,因此您可以按随机顺序对其进行排序,并选择10个顶级项目:

   Finalists1 = People1
     .OrderByDescending(item => 1)   // if people have some points, bonuses etc.
     .ThenBy(item => Guid.NewGuid()) // shuffle among peers
     .Take(10)                       // Take top 10
     .ToArray();                     // materialize as an array

如果人们被选中进入决赛并非完全随机(例如选手可以获得积分,奖金等),请更改.OrderByDescending(item => 1),例如

     .OrderByDescending(item => item.Bonuses)

如果您不想使用 Linq ,则可以从People中抽取urn而不返回:

     private static Random random = new Random();  

     ... 

     List<People> urn = new List<People>(People1); 

     for (int i = 0; i < Finalists1.Length; ++i) {
       int index = random.Next(0, urn.Count);

       Finalists1[i] = urn[index];
       urn.RemoveAt(index);
     } 

答案 1 :(得分:2)

您可以保存已绘制的列表或哈希数字集。然后再次掷骰子以获得另一个随机数。

Random rand = new Random();

HashSet<int> drawnNumbers = new HashSet<int>();
for (int i = 0; i < Finalists1.Length; i++)
{
    do
    {
        num = rand.Next(0, People1.Length);
    }
    while (drawnNumbers.Contains(num));

    Finalists1[i] = People1[num];
}

答案 2 :(得分:0)

您可以将Finalists1的类型更改为HashSet,但不允许重复。 然后将循环更改为

while(Finalists1.Length < 10)
{
    // random pick from array People1 (you don't need to create a new one)
    num = rand.Next(0, People1.Length);
    var toAdd = People1[num];
    // add to hash-set. Object won't be added, if already existing in the set
    Finalists1.Add(toAdd);
}

如果您确实需要创建要添加到哈希集的新对象,则可能需要覆盖类Equals的{​​{1}}方法。

答案 3 :(得分:0)

将People1中的每个选定元素与数组的末尾交换,并递减数组结束索引,以便您只选择下一次迭代中剩下的内容。

People tempPerson = new People;
int lastElem = People1.length - 1;
for (int i = 0; i < Finalists1.Length; i++)
{
    num = rand.Next(0, lastElem + 1);           
    Finalists1[i] = People1[num];

    //swap last entry in People1 with People1[num]
    tempPerson = People1[num];
    People1[num] = People1[lastElem];
    People1[lastElem] = tempPerson;

    lastElem--;
}

很抱歉,如果出现语法错误,我现在主要使用Java和C#。

BTW您不必单独设置字段,因为每个数组都存储Person类型的对象。

答案 4 :(得分:0)

您可以对人员数组进行分组,并选择不同的方式。 如果您使用列表,则可以从列表中删除人员 `var peopleArray = new People [40];

        var peopleCollection = peopleArray.GroupBy(p => new { p.age, p.firstname, p.lastname }).Select(grp => grp.FirstOrDefault()).ToList();

        var finalists = new People[10];


        var rand = new Random();

        for (var i = 0; i < finalists.Length; i++)
        {
            var index = rand.Next(0, peopleCollection.Count);
            var person = peopleCollection[index];

            finalists[i].lastname = person.lastname;
            finalists[i].firstname = person.firstname;
            finalists[i].age = person.age;

            peopleCollection.Remove(person);
        }

答案 5 :(得分:0)

洗牌并取前10个,例如

People1.Shuffle();
Finalists1= People1.Take(10).ToArray();

您可以从StackOverflow中找到随机播放代码或搜索“Fisher-Yates shuffle C#”以下方法取自This SO Post。阅读答案以获取有关为什么不使用GUID等的更多信息。

public static class ThreadSafeRandom
  {
      [ThreadStatic] private static Random Local;

      public static Random ThisThreadsRandom
      {
          get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId))); }
      }
  }

  static class MyExtensions
  {
    public static void Shuffle<T>(this IList<T> list)
    {
      int n = list.Count;
      while (n > 1)
      {
        n--;
        int k = ThreadSafeRandom.ThisThreadsRandom.Next(n + 1);
        T value = list[k];
        list[k] = list[n];
        list[n] = value;
      }
    }
  }