Accepted answer

EDIT: I hadn't noticed the break; before

If there could be more than one type with the relevant ID, then you need to use FirstOrDefault as per Keith's answer or my second code sample below.

EDIT: Removing "multi-from" version as it's unnecessarily inefficient assuming equality/hashcode works for whatever the type of type.Id is.

A join is probably more appropriate though:

var query = from s in vars
            join type in statusList on s equals type.Id
            select new NameValuePair(type.Id, type.Text);

foreach (var pair in query)

You might want to make an AddRange method which takes an IEnumerable<NameValuePair> at which point you could just call AddRange(query).

Alternatively, you can use a LookUp. This version makes sure it only adds one type per "s".

var lookup = types.ToLookup(type => type.Id);
foreach (var s in vars)
    var types = lookup[s];
    if (types != null)
        var type = types.First(); // Guaranteed to be at least one entry
        Add(new NameValuePair(type.Id, type.Text));

The benefit of this is that it only goes through the list of types once to build up a dictionary, basically.


Something like this:

foreach(var s in vars) {
    var type = statusList.FirstOrDefault(t => t.Id == s);
    if (type != null)
        Add(new NameValuePair(type.Id, type.Text));

Or if vars supports ForEach method, this would work too (however I recommend against overLINQifying):

vars.ForEach(s => {
    var type = statusList.FirstOrDefault(t => t.Id == s);
    if (type != null)
       Add(new NameValuePair(type.Id, type.Text));

I assumed type is an instance of a reference type.



var types =
    from s in vars
    let type = (
        from tp in statusList
        where tp.Id == s ).FirstOrDefault()
    where type != null
    select new NameValuePair(type.Id, type.Text)


Bart de Smet has an implementation of an extension ForEach for IEnumerable.


If your Add method is constructing a list, you might also try:

IEnumarable<NamedValuePair> result = statusList.Where(type => type.Id == s).Select(new NameValuePair(type => type.Id, type.Text));


I don't see an answer with a group join, so here's one:

var result = vars
    s => s,
    type => type.Id,
    (s, g) => g.Any() ? g.First() : null
  .Where(type => type != null)
  .Select(type => new NameValuePair(type.Id, type.Text));

Related Articles