1
public class Derp
{
    public Derp
    {
        listOfStrings = new List<string>();
    }
    public string strName;
    public List<string> listOfStrings;
    public int unrequiredInt;
    public bool unrequiredBool;
}

List<Derp> derp1 = ... //generate data assume strName is unique in list, but not across lists;
List<Derp> derp2 = ... //generate data;
List<Derp> derp3 = ... //generate data;

List<Derp> mergedDerp = new List<Derp>();

I need to merge derp1 and derp2 and derp3 with the condition derp1[x].strName == derp2[y].strName == derp3[z].strName. The merged list should have all Derps but merge derp1,2,3 into one derp based on the condition above (unrequiredInt and unrequiredBool's content doesn't matter). I know it can be done in LINQ but I'm quite at a loss. Something like ...

mergedDerp = derp1.Join(derp2, d1 => derp1, d2 => derp2, (d1,d2) => new { ... ;
//and the next derp would be (i assume)
mergedDerp = mergedDerp.Join(derp3, md => mergedDerp, ...;

But i'm not getting it.

The result should contain a list of unique Derps by their strName, and if any Derps were merged, the listOfStrings should all be appended into the new Derp.

2 Answers 2

1

Using GroupBy instead of Join seems more suitable in your case:

var mergedDerp = derp1.Union(derp2).Union(derp3).GroupBy(x => x.strName)
    .Select(x => new Derp
        {
            strName = x.Key,
            // I guess you want to merge the list of strings as well?
            listOfStrings = x.SelectMany(d => d.listOfStrings).ToList()
            // Leave unrequired fields as default or just use the first derp's value
            // unrequiredInt = x.First().unrequiredInt,
            // unrequiredBool = x.First().unrequiredBool,
        })
    .ToList();
Sign up to request clarification or add additional context in comments.

1 Comment

THANKS. :O Initially tested your code with John's extra Equals and GetHashCode within Derp so it didn't work. Now that I've removed it, it works! This is amazing. Thanks again.
1

It sounds like you want to determine equality based on the strName value. If so, simply implement the Equals and GetHashCode methods on the object:

public class Derp
{
    public Derp()
    {
        listOfStrings = new List<string>();
    }

    public string strName;
    public List<string> listOfStrings;
    public int unrequiredInt;
    public bool unrequiredBool;


    public override bool Equals(object obj)
    {
        return ((Derp) obj).strName.Equals(strName);
    }

    public override int GetHashCode()
    {
        return strName.GetHashCode();
    }
} 

Then when you combine them, you can just use Union and Distinct:

var derp1 = new List<Derp>();
derp1.Add(new Derp() {strName = "X"});
derp1.Add(new Derp() { strName = "Y" });
derp1.Add(new Derp() { strName = "Z" });

var derp2 = new List<Derp>();
derp2.Add(new Derp() {strName = "A"});
derp2.Add(new Derp() { strName = "B" });
derp2.Add(new Derp() { strName = "X" });


var derp3 = new List<Derp>();
derp3.Add(new Derp() { strName = "J" });
derp3.Add(new Derp() { strName = "B" });
derp3.Add(new Derp() { strName = "X" });


var merged = derp1.Union(derp2.Union(derp3)).Distinct();

Console.WriteLine(merged.Count());   // Returns 6: X, Y, Z, A, B, J

1 Comment

Hi John, thanks for your prompt and detailed response. This would be good if the List<string> listOfStrings didn't matter, however I'd need for the listOfStrings to be appended along with the union. I'd reckon there could be methods I could implement in the Derp class, but I was thinking if there could be any LINQ ways (so I can level up a little)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.