tags:

views:

152

answers:

1

I'm having a logic problem trying to return a collection of objects from a collection where the PersonId is contained in the personId of the first object.

This sounds hideously complicated, but here it is:

//classes
public class MyClass
{
  public List<int> People { get; set; }
}

//Code
List<MyClass> myClasses = new List<MyClass>()
{
  new MyClass()
  {
    People = new List<int>()
    {
      1,
      2
    }
  },
  new MyClass()
  {
    People = new List<int>()
    {
      1
    }
  },
  new MyClass()
  {
    People = new List<int>()
    {
      2
    }
  },
  new MyClass()
  {
    People = new List<int>()
    {
      3,
      4
    }
  },
  new MyClass()
  {
    People = new List<int>()
    {
      4
    }
  }
};

Basically I would like to return all instances of MyClass where the People contains any of the integers of the people in the first instance of MyClass.

Once I've got them, I would then do some work on them, and then delete them from myClasses, and start again until I return an empty collection.

So, my first run would return the first three instances of MyClass. I'd do some work on them, and then delete them.

My second run would return the fourth and fifth (which, because the first three are deleted would be the first and second).

Is this possible? Am I looking at this the wrong way?

I thought that this would be a sort of 'ContainsAny' query.

Edit: Made a mistake, but it's fixed.

+3  A: 
while (myClasses.Any())
{
    var people = myClasses.First().People;
    var q = from c in myClasses
            where c.People.Any(p => people.Contains(p))
            select c;
    DoWork(q);
    myClasses.RemoveAll(c => q.Contains(c));
}

There's a problem with the specification, though. People could be an empty list. If this is invalid, the method above should probably throw if it's encountered.

Alternate method would be to put this in a static class:

public static bool ContainsAny<TSource>(
    this IEnumerable<TSource> source, 
    IEnumerable<TSource> values)
{
    return source.Any(o => values.Contains(o));
}

Then call this above.

Craig Stuntz
Thank you for your answer, but I get this error in relation to people.Contains(p): The type arguments for method 'System.Linq.Enumerable.Any<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,bool>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Dan Atkinson
Any<Person>(p => people.Contains(p))
Joren
What are the types of "people" (hover the mouse cursor over the "var") and c.People (hover the mouse cursor over the "People" in c.People)?
Craig Stuntz
The problem is the code in the question won't compile. MyClass.People is List<Person>, so it can't be initialized with a List<int>
Craig Stuntz
Craig, thanks for your answer. I used Joren's bit of code in the where, and that fixed it. Joren, thanks also for your help! Much appreciated!
Dan Atkinson