我有一个班级:
public class Doc
{
public int Id {get; set;}
public string Name {get; set;}
public bool IsActive {get; set;}
}
两个Doc
类型的列表。
如果包含来自第二个列表的id,如何编写LINQ来比较这些列表并更改第一个列表的IsActive
属性。
答案 0 :(得分:4)
鉴于您的目标列表名为targetDocs
,并且您要检查文档存在的列表是srcDocs
,请尝试类似的内容(无法访问编译器,因此可以&#39 ; t test):
targetDocs.ForEach(d => d.IsActive = srcDocs.Any(sd => sd.id == d.Id))
我假设我们正在谈论List
而不是其他集合类型,因为为List
定义了ForEach扩展方法。
答案 1 :(得分:1)
最好将HashSet<T>
集合用于此类操作,它具有快速O(1)查找,并且没有真正的理由在此处使用LINQ来更改属性值。没错,我们必须在这里创建另一个集合,并且需要时间来分配资源来初始化它等等。但是如果有一百万条记录,它将会带来巨大的性能提升。
如果docs2集合具有Id,则docs1是您希望将IsActive更改为true的集合,您可以使用:
var ids = new HashSet<int>(docs2.Select(d => d.Id));
foreach(var doc in docs1)
{
// .Contains implementation in HashSet has fast O(1) lookups
doc.IsActive = ids.Contains(doc.Id);
}
答案 2 :(得分:0)
您可以创建自己的静态方法,该方法负责检查活动属性。我在这里使用了枚举器,它工作起来快速且易于理解。
static class Program
{
static void Main(string[] args)
{
List<Data> firstInstance = new List<Data>
{
new Data { Id = 1, IsActive = false },
new Data { Id = 2, IsActive = false }
};
List<Data> secondInstance = new List<Data>
{
new Data { Id = 1, IsActive = false },
new Data { Id = 3, IsActive = false }
};
firstInstance.CheckActive(secondInstance);
}
static void CheckActive(this List<Data> firstInstance, List<Data> secondInstance)
{
using (IEnumerator<Data> firstEnumerator = firstInstance.GetEnumerator(), secondEnumerator = secondInstance.GetEnumerator())
{
while (true)
{
if (!firstEnumerator.MoveNext() || !secondEnumerator.MoveNext()) break;
if (firstEnumerator.Current.Id == secondEnumerator.Current.Id) firstEnumerator.Current.IsActive = true;
}
}
}
}
class Data
{
public int Id { get; set; }
public bool IsActive { get; set; }
}
答案 3 :(得分:0)
您写道:
如何编写linq来比较这些列表并更改&#34; IsActive&#34;如果包含来自第二个列表的id,则第一个列表的符号。
您的第一个列表没有IsActive属性,但列表中的元素有一个。因此,我假设您需要以下内容:
如何获取第一个列表中所有元素的序列,其中第二个列表中包含任何元素的Id,因此我可以更改这些元素的IsActive属性。
LINQ用于枚举对象。您无法更改linq语句中的对象
如果要更改对象,则必须对它们进行枚举,例如使用ForEach。
IEnumerable<int> activeIds = secondList.Select(item => item.Id);
IEnumerable<Doc> activeDocs = firstList.Where(item => activedIds.Contains(item.Id));
foreach (Doc activeDoc in activeDocs)
{
activeDoc.IsActive = true;
}
注意:我没有为所有inActive文档更改ISActive。如果你想要,你必须预先知道firstList中的所有元素:
IEnumerable<int> activeIds = secondList.Select(item => item.Id);
foreach (Doc doc in firstList)
{
doc.IsActive = activeIds.Contains(doc.Id);
}
答案 4 :(得分:-1)
您可以在不使用linq的情况下使用此解决方案
foreach(Doc x in list1){
foreach(Doc y in list2){
if(x.id == y.id){
y.IsActive = true;
}
}
}