简体   繁体   中英

How to compare two lists and change one property

I have a class:

public class Doc
{
   public int Id {get; set;}
   public string Name {get; set;}
   public bool IsActive {get; set;}
}

And two lists of Doc type.

How to write LINQ to compare these list and change IsActive property of first list if contains id from second list.

Given that your target list is named targetDocs and the list you want to check for document existance is srcDocs try something like (don't have access to a compiler here so can't test):

targetDocs.ForEach(d => d.IsActive = srcDocs.Any(sd => sd.id == d.Id))

I'm assuming that we are talking about List s and not other collection types as the ForEach extension method is defined for List s.

It's better to use the HashSet<T> collection for such operations, it has fast O(1) lookups and there is no real reason to use LINQ for changing property values here. True, we have to create another collection here and it takes time to allocate resources initialize it etc. but if there is one million records it will give huge performance boost.

Provided that docs1 is collection where you would like to change IsActive to true if docs2 collection has Id, you can use :

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); 
}

You can create your own static method which is responsible for checking active property. I've used enumerators here, it works fast and easy to understand.

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; }
}

You wrote:

How to write linq to compare these list and change "IsActive" propety of first list if contains id from second list.

Your first list does not have an IsActive property, however the elements of your list have one. Therefore I assume you want the following:

How do I get a sequence of all elements in the first list that have an Id of any of the elements in the second list, so I can change the IsActive properties of those elements.

LINQ is used to enumerate over objects. You can't change the object in the linq statement

If you want to change the objects, you'll have to enumerate over them, for instance with 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;
}

Beware: I did not change ISActive for all inActive docs. If you want that you'll have to foreach all elements from your firstList:

IEnumerable<int> activeIds = secondList.Select(item => item.Id);
foreach (Doc doc in firstList)
{
    doc.IsActive = activeIds.Contains(doc.Id);
}

You can use this solution without using linq

foreach(Doc x in list1){ 
  foreach(Doc y in list2){
    if(x.id == y.id){
       y.IsActive = true;
                    }
                        }
                      }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM