Код здесь находится в C# и VB. Net.
Используя LINQ, вы можете легко группировать по Col1
, а затем сравнивать группы. Я использовал Aggregate
для обработки, когда Col1
имеет больше значений, чем просто yes
и no
.
var ans = dt.AsEnumerable()
.GroupBy(r => r.Field<string>("Col1"), r => r.Field<string>("Col2"))
.Aggregate(default(IEnumerable<string>), (ans, dg) => (ans == null) ? dg : ans.Intersect(dg));
В VB. Net это будет
Dim res = dt.AsEnumerable _
.GroupBy(Function(r) r.Field(Of String)("Col1"), Function(r) r.Field(Of String)("Col2")) _
.Aggregate(CType(Nothing, IEnumerable(Of String)), Function(ans, dg) If(ans Is Nothing, dg, ans.Intersect(dg)))
Существуют варианты, которые могут вернуть все DataRow
или все совпадающие DataRow
s, но они требуют создания специальных IEqualityComparer
s или использования гораздо более сложных выражений LINQ с Where
/ Any
/ Concat
для объедините их.
Например, это возвращает оба совпадения DataRow
s для каждого Col2
совпадения:
var ans = dt.AsEnumerable()
.GroupBy(dr => dr.Field<string>("Col1"))
.Aggregate(default(IEnumerable<DataRow>),
(ans, drg) => (ans == null) ? drg
: ans.Where(ls => drg.Any(dr => dr.Field<string>("Col2") == ls.Field<string>("Col2")))
.Concat(drg.Where(dr => ans.Any(ls => ls.Field<string>("Col2") == dr.Field<string>("Col2"))))
);
ПРИМЕЧАНИЕ: Intersect
довольно эффективен по времени, хотя и использует дополнительные пространство для создания простого Set
из второй коллекции. Второй пример не особенно эффективен по времени или пространству, и его лучше было бы сделать с пользовательскими IEqualityComparer
и Intersect
.