Linq, получи отдельные элементы, сгруппированные по полю - PullRequest
2 голосов
/ 12 августа 2011

Я чувствую себя глупо, но я должен признать, мне нужна ваша помощь, ребята, казалось бы, легко найти правильный ответ

 public class Foo
 {
     public string Name { get; set; }
     public string Time { get; set; }

     public Foo(string name, string time)
     {
        Name = name;
        Time = time;
     }
 }

var o = new List<Foo>
                  {
                      new Foo("Breakfast","9:00"),
                      new Foo("Lunch", "12:00"),
                      new Foo("Breakfast", "8:00")
                  };

Как получить только завтрак в 9:00 и обед, а не завтракать в 8?

Я начал так:

var a = o.GroupBy(x => x.Name);

Но это даст вам только Имя, где мне тоже нужно Время.

Ответы [ 3 ]

5 голосов
/ 12 августа 2011
var a = o.GroupBy(x => x.Name).Select(g => g.First())

Но подумайте об этом вызове .First (). Как вы хотите выбрать правильный элемент, когда их более одного - вы можете отсортировать элементы, чтобы получить самые последние / самые ранние или любые другие требования.

3 голосов
/ 12 августа 2011

Один из вариантов:

var a = o.GroupBy(x => x.Name)
         .Select(g => g.First());

Или вы можете использовать DistinctBy из MoreLINQ :

var a = o.DistinctBy(x => x.Name);

Последний более эффективен в памяти и немедленно начнет давать результаты, тогда как первый подход должен прочитать все данные, прежде чем они смогут что-либо вернуть. С другой стороны, для последнего требуется MoreLINQ (или копирование кода).

РЕДАКТИРОВАТЬ: Здесь я предполагаю СВЯЗЬ с объектами (поскольку MoreLINQ, конечно, не будет работать с другими поставщиками) и что вы довольны первым появлением любой группы, представляющей эту группу.

0 голосов
/ 12 августа 2011

Почему не что-то вроде следующего? (Я также взял на себя смелость сделать ваш код немного меньше - я думаю, что поскольку ваши свойства общедоступны, вам не нужен конструктор, но вместо этого можно просто использовать синтаксис object-initializer. Все это должно работать в LinqPad: *

void Main() {
    var os = new [] {
        new Foo{Name="Breakfast",Time="9:00"},
        new Foo{Name="Lunch", Time="12:00"},
        new Foo{Name="Breakfast", Time="8:00"}
    };

    os.Where(o => DateTime.Parse(o.Time).Hour > 8).Dump();
}

public class Foo
{
    public string Name { get; set; }
    public string Time { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...