-4

I have 3 lists.

ListA<items>
ListB<items>
ListC<items>

I have to select one item from each list but the item.itemID should be unique for each of those items. How can i achieve this? Thanks in advance.

AJ_NY
  • 59
  • 1
  • 8
  • use [Concat](https://msdn.microsoft.com/en-us/library/bb302894(v=vs.110).aspx) then [Distinct](https://msdn.microsoft.com/en-us/library/vstudio/bb348436(v=vs.100).aspx) – Grundy Mar 17 '15 at 16:19
  • 3
    Distinct will only work if he makes a compare or the object references are the same or items is a struct – TheCatWhisperer Mar 17 '15 at 16:20
  • @TheCatWhisperer Distinct works if the objects are comparable -- not just the same references or struct or simple obejct. However, concat + distinct doesn't meet his criteria. – Robert McKee Mar 17 '15 at 17:23
  • You are correct, IF they are comparable... – TheCatWhisperer Mar 17 '15 at 17:25

3 Answers3

3
List<items> concat = new List<items>();
concat.AddRange(ListA);
concat.AddRange(ListB);
concat.AddRange(ListC);

List<items> result = new List<items>();
foreach (var item in concat)
{
   if (result.Where(x => x.itemId == item.itemId).Count() == 0)
   {
       result.add(item);
   }
}
//result should now contain what you are looking for
TheCatWhisperer
  • 901
  • 2
  • 12
  • 28
  • This won't work because it can multiple answers from ListA instead of one from each list. – Robert McKee Mar 17 '15 at 17:19
  • I have to get one item from each list. I don't think this logic will take care of that requirement as the lists are concatenated here. – AJ_NY Mar 17 '15 at 17:19
1

So you want exactly one item from each list, where that item hasn't been selected already from a previous list?

Then select from the lists where the ID isn't in the previous selection. Maybe something like this:

var itemA = listA.First(); // any item is unique, since this is our first one
var itemB = listB.First(b => b.ID != itemA.ID);
var itemC = listC.First(c => c.ID != itemA.ID && c.ID != itemB.ID);

If the count of lists isn't known then we'd need to make this a little more dynamic. Maybe something like this:

var selectedItems = new List<Item>();
foreach (var list in listOfLists)
    selectedItems.Add(list.First(x => selectedItems.Count(y => y.ID == x.ID) == 0));

What this does is loop through the "list of lists" (since the number of lists isn't known, it must be in a collection data structure) and get the first item from each one where the currently known selected items do not have a matching ID. This should result in one selected item from each list.

(This all assumes that the lists contain a valid item that you're looking for. If that's not the case, you might use FirstOrDefault() instead and check for nulls.)

David
  • 208,112
  • 36
  • 198
  • 279
0
public class items 
{
    public int id {get;set;}
}
void Main()
{
    var l1=new List<items>{new items {id=1}, new items {id=2}, new items {id=3}};
    var l2=new List<items>{new items {id=2}, new items {id=3}, new items {id=4}};
    var l3=new List<items>{new items {id=1}, new items {id=2}};
    var result=l1
            .Join(l2,(k1)=>true,(k2)=>true,(a1,a2)=>new {a1,a2})
            .Join(l3,(k1)=>true,(k2)=>true,(b1,b2)=>new {b1.a1,b1.a2,a3=b2})
            .Where(rec=>rec.a1.id!=rec.a2.id && rec.a2.id!=rec.a3.id && rec.a1.id!=rec.a3.id)
            .First();
    Console.WriteLine("{0},{1},{2}",result.a1.id,result.a2.id,result.a3.id);
}

Of the possible answers (132,142,231,241,321,341,342) it will pick and return the first one (132).

Example code: http://csharppad.com/gist/98a076bdd4e01dbd82be

Robert McKee
  • 21,305
  • 1
  • 43
  • 57