Abhishek
Abhishek

Reputation: 215

How to compare two lists and change one property from one list?

I have two lists. I want to compare two lists and change the Selected bool property false to true from firstInstance if the selectedInstance list items should have in the firstInstance list. I have tried below code using IEnumerator but not getting as expected.

I am expecting the output:

 List<Data> firstInstance = new List<Data>
    {
        new Data { AccountNo = 1001,AccountName="AccountName1",BranchName="BranchName1", Selected = false },
        new Data { AccountNo = 1101,AccountName="AccountName2",BranchName="BranchName2", Selected = true},
        new Data { AccountNo = 1051,AccountName="AccountName3",BranchName="BranchName3", Selected = false },
        new Data { AccountNo = 1991,AccountName="AccountName4",BranchName="BranchName4", Selected = true},
        new Data { AccountNo = 1234,AccountName="AccountName5",BranchName="BranchName5", Selected = false },
    };

I have tried below code:-

static class Program
{
    static void Main(string[] args)
    {
    List<Data> firstInstance = new List<Data>
    {
        new Data { AccountNo = 1001,AccountName="AccountName1",BranchName="BranchName1", Selected = false },
        new Data { AccountNo = 1101,AccountName="AccountName2",BranchName="BranchName2", Selected = false },
        new Data { AccountNo = 1051,AccountName="AccountName3",BranchName="BranchName3", Selected = false },
        new Data { AccountNo = 1991,AccountName="AccountName4",BranchName="BranchName4", Selected = false },
        new Data { AccountNo = 1234,AccountName="AccountName5",BranchName="BranchName5", Selected = false },
    };

    List<Data> selectedInstance = new List<Data>
    {
         new Data { AccountNo = 1991,AccountName="AccountName4",BranchName="BranchName4", Selected = true },
        new Data { AccountNo = 1101,AccountName="AccountName2",BranchName="BranchName2", Selected = true }
    };

        firstInstance.CheckActive(selectedInstance);
    }

    static void CheckActive(this List<Data> firstInstance, List<Data> selectedInstance)
    {
        using (IEnumerator<Data> firstEnumerator = firstInstance.GetEnumerator(), secondEnumerator = selectedInstance.GetEnumerator())
        {
            while (true)
            {
                if (!firstEnumerator.MoveNext() || !secondEnumerator.MoveNext()) break;
                if (firstEnumerator.Current.AccountNo == secondEnumerator.Current.AccountNo) firstEnumerator.Current.Selected = true;
            }
        }
    }
}

class Data
{
    public int AccountNo { get; set; }
    public string AccountName { get; set; }
    public string BranchName { get; set; }
    public bool Selected { get; set; }
}

Upvotes: 2

Views: 114

Answers (4)

Rufus L
Rufus L

Reputation: 37020

One way would be to find all the instances in firstInstance where the AccountNo of the item matches the AccountNo of Any of the items in the selectedInstance list, and set the Selected property of those items to true in a foreach loop:

foreach (var item in firstInstance.Where(first => 
    selectedInstance.Any(selected => selected.AccountNo == first.AccountNo)))
{
    item.Selected = true;
}

Upvotes: 1

Hossein Sabziani
Hossein Sabziani

Reputation: 3495

edit this line of code:

   // firstInstance.CheckActive(selectedInstance);
    CheckActive(firstInstance,selectedInstance)

and use this function...

    public static void CheckActive(List<Data> firstInstance, List<Data> selectedInstance)
    {
        var result = firstInstance.Where(y => selectedInstance.Any(z => z.AccountNo == y.AccountNo)).ToList();
        foreach (var _item in firstInstance)
        {
            if (result.Any(z => z.AccountNo == _item.AccountNo))
            {
                _item.Selected = true;
            }
        }
    }

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460038

So you want to set the Selected property to true for all items in the first list which match with the second list, that only contains selected items?

Then this Join approach is efficient and works:

var query = from activeData in selectedInstance
            join allData in firstInstance 
            on activeData.AccountNo equals allData.AccountNo 
            select allData;

foreach(Data selectedData in query)
{
    selectedData.Selected = true;
}

Your approach does not work because you stop enumeration if one list is at the end. But you have to enumerate the other list(which contains all data) until end. You also have to compare each item with all other items, not just at the same index.

Upvotes: 2

Shay
Shay

Reputation: 1768

Not sure why you'd need both enumerators iterating together. The collections' size doesn't seem to match.

I would do something much simpler:

var selectedAccounts = selectedInstance.Select(d => d.AccountNo).ToList();
foreach (var selected in firstInstance.Where(d => selectedAccounts.Contains(d.AccountNo)))
{
    selected.Selected = true;
}

This is assuming you are not trying to account for performance and big data structures.

Upvotes: 1

Related Questions