Использование LINQ для выделения определенного объекта из списка объектов - PullRequest
1 голос
/ 18 мая 2010

альтернативный текст http://img707.yfrog.com/img707/6250/newpicturer.jpg

Я пытаюсь сделать клон захватчиков. на экране 30 иностранцев, расположенных в матрице 5х6. Мне нужно дать нижнему большинству пришельцев возможность выстрелить. Я использую LINQ, чтобы сгруппировать пришельцев в 5 групп на основе Location.X, а затем отсортировать группы по убыванию. Затем мне нужно выбрать одну из групп (которая дает мне 5 групп). и выберите первого пришельца в группе и используйте его; его координату, чтобы выстрелить.

Мой код ниже, хорошо, работает, но инопланетяне в ЛЮБОМ ряду весело стреляют - не только самые нижние. Пожалуйста, посмотрите на мой код ниже и скажите, что не так. (r = экземпляр класса Random, все инопланетяне находятся в списке, называемом invaders).

 {
           var query = (from inv in invaders
                         group inv by inv.Location.X
                         into invgroup
                         orderby invgroup.Key descending 
                         select invgroup).ToList();

            var invfirst = query[r.Next(query.Count)].First();


                invaderShots.Add(new Shot(
                        new Point(invfirst.Area.X + invfirst.Area.Width / 2, invfirst.Area.Y + invfirst.Area.Height + 5),
                        displayrect, Shot.Direction.Down));

        }

EDIT:

Решено. Теперь все работает, как требуется, после того, как Дэвид Б. толкнул меня в правильном направлении.

Финальный код ниже. Определенно могут потребоваться некоторые улучшения в свете большого количества группировок / сортировок. Если у кого-то есть что-то конструктивное, чтобы сказать по этому поводу, я все уши (или глаза, в данном случае). Спасибо всем, кто помог.

   List<Invader> firstinvader = invaders.GroupBy(inv => inv.Location.X)
                .Select(g => g.OrderByDescending(inv => inv.Location.Y)).ElementAt(r.Next(5)).ToList();

            firstinvader.Sort(comparerByLocation);
            Invader item = firstinvader[firstinvader.Count -1];

            if(invaderShots.Count < 2)
            {
                invaderShots.Add(new Shot(
                     new Point(item.Area.X + item.Area.Width / 2, item.Area.Y + item.Area.Height / 2),
                     displayrect, Shot.Direction.Down));

            }
            else
            {
                return;

            }

Ответы [ 3 ]

1 голос
/ 18 мая 2010

Вы группируете по Location.X, который я собираюсь угадать - это столбец . Затем вы упорядочиваете эти группы по номеру столбца - обратите внимание, что это упорядочивает группы , а не элементы внутри групп. Так как вы выбираете случайную группу, тот факт, что вы их заказали, не имеет значения. После того, как вы выбрали случайную группу - случайный столбец исходных инопланетян - вы выбираете First группы, но поскольку инопланетяне не упорядочены в пределах групп, вы получаете произвольного инопланетянина .

Чтобы это исправить, вам нужно убедиться, что группы упорядочены по высоте (я думаю, Location.Y), чтобы при выборе First выбранной группы случайно это самый нижний инопланетянин. Изменить

select invgroup).ToList();

до

select invgroup.OrderBy(inv => inv.Location.Y)).ToList();

(при условии, что ваша ось Y движется в правильном направлении, чтобы получить желаемое!)

1 голос
/ 18 мая 2010
List<Invader> firstInvaders = invaders
  .GroupBy(inv => inv.Location.X)
  .Select(g => g
     .OrderByDescending(inv => inv.Location.Y)
     .First())
  .ToList();

Invader shooter = firstInvaders[r.Next(firstInvaders.Count)];
1 голос
/ 18 мая 2010

Вы заказываете группы , но не заказываете invaders . Вполне возможно, что это сделает это:

var query = (from inv in invaders
             group inv by inv.Location.X
             into invgroup
             orderby invgroup.Key descending 
             select invgroup.OrderBy(inv => inv.Location.Y)).ToList();

(Вы можете сделать заказ по убыванию, в зависимости от того, Y вверх или вниз.)

Хотя это может сработать, я не уверен, что выполнение всей этой сортировки все время является идеальным ... разве вы не можете сохранить захватчики в структуре данных, которая поможет вам сделать это проще?

...