0

I have a list of customObject, I want to group the "CustomObject" by the List property of the CustomObject object.

 public class CustomObject
{
    public string Name { get; set; }

    public List<string> List { get; set; }

    public CustomObject(string name, List<string> list)
    {
        this.Name = name;
        this.List = list;
    }
}

.....................

List<CustomObject> listCustomObject = new List<CustomObject>()
        {
            new  CustomObject("A", new List<string>(){ "1","2","3", "4"} ),
            new  CustomObject("B", new List<string>(){ "4","8","5"}),
            new  CustomObject("C", new List<string>(){ "5","1","2", "4"})
        };

Desired results :

"A"/"C" => identical item in the list ("1", "2")

"A"/"B"/"C" => identical item in the list ("4")

"B"/"C" => identical item in the list ("5")

Axel
  • 21
  • 7

1 Answers1

0

Using some extension methods, you can generate all combinations of the inputs having at least two members:

public static IEnumerable<IEnumerable<T>> AtLeastCombinations<T>(this IEnumerable<T> elements, int minK) => Enumerable.Range(minK, elements.Count()+1-minK).SelectMany(k => elements.Combinations(k));
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k) {
    return k == 0 ? new[] { new T[0] } :
      elements.SelectMany((e, i) =>
        elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] { e }).Concat(c)));
}

Now you can simply test each combination to see if they have any common elements:

var ans = listCustomObject.AtLeastCombinations(2)
                          .Select(c => new { CombinationNames = c.Select(co => co.Name).ToList(), CombinationIntersect = c.Select(co => co.List).Aggregate((sofar, coList) => sofar.Intersect(coList).ToList()) })
                          .Where(ci => ci.CombinationIntersect.Count > 0)
                          .ToList();
NetMage
  • 26,163
  • 3
  • 34
  • 55