简体   繁体   中英

Find a string in the list and change value of another property using linq (complicated)

I have two List with a common property i need to compare both and change the final list accordingly

class ClassA
{
    public string Property1 { get; set; }
    public List<ClassB> LstClassB { get; set; }
}

class ClassB
{
    public string PropertyToCompare { get; set; }
    public string Property2 { get; set; }
}
class ClassC
{
    public string Property { get; set; }
    public List<ClassB> LstClassB { get; set; }
}
class ClassD : ClassA
{
    public bool PropertyToChange { get; set; }
}


 void fun()
    {
        List<ClassC> LstClassC = new List<ClassC>();
        //populate LstClassC

        List<ClassD> LstClassD = new List<ClassD>();
        //populate LstClassD
        foreach (var objectC in LstClassC)
        {
            foreach (var objectBFromClassC in objectC.LstClassB)
            {
                foreach (var objectD in LstClassD)
                {
                    foreach (var objectBFromD in objectD.LstClassB)
                    {
                        if (objectBFromD.PropertyToCompare == objectBFromClassC.PropertyToCompare)
                            objectD.PropertyToChange = newValue;
                    }
                }

            }
        }
    }

so this is what i want to change in LINQ in a efficient way within the list since the LstD is bound to a DataGrid, so everytime i update the value for PropertyToChange based on the same condition i want it to be reflected in DataGrid

You can use SelectMany to flatten each of the two lists of lists that you have into lists of the child elements, and then you can Join those two lists together based on the common property. Using Join will be able to use a hash-based lookup to find the matching items from each collection, which will be a lot faster than looking through every single combination, as you're currently doing iteratively.

var query = from d in LstClassD
            from dChild in d.LstClassB
            join cChild in LstClassC.SelectMany(c => c.LstClassB)
            on dChild.PropertyToCompare equals cChild.PropertyToCompare
            into matches
            where matches.Any()
            select d;
foreach (var d in query)
    d.PropertyToChange = newValue;

I can't comment on how efficient this is, however I'd use Linq's Intersects function.

If you want the below code in an interactive format go to this link https://dotnetfiddle.net/x1gIXQ

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {       
        var x = new List<String>();
        x.Add("Hello");
        x.Add("Hola");
        x.Add("Aloha");

        var y = new List<String>();
        y.Add("Goodbye");
        y.Add("Adios");
        y.Add("Aloha");

        var intersects = x.Intersect(y);
        intersects.ToList().ForEach(zz=> Console.WriteLine(zz));

    }
}

If you want more information about the intersects function check it out here. https://msdn.microsoft.com/en-us/library/vstudio/bb460136%28v=vs.100%29.aspx

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