Выберите выделение, используя linq
У меня есть список классов класса
public class LinqTest
{
public int id { get; set; }
public string value { get; set; }
}
List<LinqTest> myList = new List<LinqTest>();
myList.Add(new LinqTest() { id = 1, value = "a" });
myList.Add(new LinqTest() { id = 1, value = "b" });
myList.Add(new LinqTest() { id = 2, value = "c" });
Мне нужно выбрать только отдельный идентификатор из этого списка.
т.е. мой результирующий список должен содержать только
[{id=1,value="a"},{ id = 2, value = "c" }]
Как это сделать с помощью linq?
Edit
Ввод
id value
1 a
1 b
2 c
3 d
3 e
Вывод должен быть,
id value
1 a
2 c
3 d
т.е. если есть повторение id
, результат должен принимать только первое вхождение.
Ответы
Ответ 1
myList.GroupBy(test => test.id)
.Select(grp => grp.First());
Изменить: как получение этого IEnumerable<>
в List<>
кажется загадкой для многих людей, вы можете просто написать:
var result = myList.GroupBy(test => test.id)
.Select(grp => grp.First())
.ToList();
Но часто лучше работать с IEnumerable
, а не IList
, так как Linq выше оценивается лениво: он фактически не выполняет всю работу до тех пор, пока перечислимый не будет повторен. Когда вы вызываете ToList
, он фактически перебирает все перечислимое, заставляя всю работу проделать вперед. (И может занять немного времени, если ваш перечислимый бесконечно длинный.)
Вкратце на этот совет заключается в том, что каждый раз, когда вы перечисляете такой IEnumerable
, работа по его оценке должна быть сделана заново. Поэтому вам нужно решить для каждого случая, лучше ли работать с лениво оцененным IEnumerable
или реализовать его в List
, Set
, Dictionary
или еще что-то.
Ответ 2
Используя morelinq, вы можете использовать DistinctBy
:
myList.DistinctBy(x => x.id);
В противном случае вы можете использовать группу:
myList.GroupBy(x => x.id)
.Select(g => g.First());
Ответ 3
Вы должны переопределить Equals
и GetHashCode
осмысленно, в этом случае сравнить ID:
public class LinqTest
{
public int id { get; set; }
public string value { get; set; }
public override bool Equals(object obj)
{
LinqTest obj2 = obj as LinqTest;
if (obj2 == null) return false;
return id == obj2.id;
}
public override int GetHashCode()
{
return id;
}
}
Теперь вы можете использовать Distinct
:
List<LinqTest> uniqueIDs = myList.Distinct().ToList();
Ответ 4
myList.GroupBy(i => i.id).Select(group => group.First())