0

I have a list:

var _books = new List<int> {233,5,20};

And a ListBox with a lot of books (their value is an item id)

How do I take this working code:

var t = from ListItem n in lbBooks.Items 
                    where _books.Contains(int.Parse(n.Value)) 
                    select n;
            foreach(ListItem i in t)
            {
                i.Selected = true;
            }

and convert it to lambda:

lbBooks.Items.Cast<ListItem>()
                .Where(n => _books.Contains(int.Parse(n.Value)))
                .Select(n => n.Selected = true);
The Muffin Man
  • 19,585
  • 30
  • 119
  • 191

4 Answers4

1

Your not far off, you need to return the whole object and set Selected to true. Something like:

lbBooks.Items.Cast<ListItem>()
                .Where(n => _books.Contains(int.Parse(n.Value)))
                .Select(n => SetSelected(n));

The above .Select can be shortend to .Select(SetSelected); if you prefer

private ListItem SetSelected(ListItem listItem)
{
    listItem.Selected = true;
    return listItem
}

Additionally to save casting you could utilise the SetSelected to handle your casting once you have just the records you want. Your query would then become:

lbBooks.Items.Where(n => _books.Contains(int.Parse(n.Value)))
             .Select(n => SetSelected(n));

private ListItem SetSelected(Item item)
{
    ListItem result = item as ListItem;
    result.Selected = true;
    return result;
}
NinjaNye
  • 7,046
  • 1
  • 32
  • 46
  • I wanted to do it using as short and concise syntax as possible, see my answer above. – The Muffin Man Jul 09 '11 at 21:19
  • Ok. That works to. Personally I prefer a more readable solution but i guess it's horses for courses – NinjaNye Jul 09 '11 at 21:23
  • what is your opinion on using your last code example vs a foreach loop? – The Muffin Man Jul 09 '11 at 21:45
  • As Magnus mentions, its means you are iterating over the collection twice. The above will only get your collection once and build a list item from that result. If it were me i wouldn't use the ForEach approach (but I'm biased) – NinjaNye Jul 09 '11 at 21:54
  • I meant the the foreach example in my first code example, not the List class foreach extension. Is that what you were referring to? – The Muffin Man Jul 09 '11 at 22:23
  • The response applies to both. In either case your iterating through a collection once more than you need to – NinjaNye Jul 09 '11 at 22:34
1

The best option? Don't. LINQ queries are supposed to be just that – queries. And queries aren't supposed to have side effects. Your approach using foreach is perfectly fine.

If you really wanted, you could create your own extension method ForEach(), similar to the one on List<T>, but I don't think that's a good idea.

svick
  • 236,525
  • 50
  • 385
  • 514
0

Cast to .ToList() and use the `ForEach' operator as so:

lbBooks.Items.Cast<ListItem>()
             .Where(n => _books.Contains(int.Parse(n.Value)))
             .Select(n => n).ToList().ForEach(n=> n.Selected=true);
svick
  • 236,525
  • 50
  • 385
  • 514
The Muffin Man
  • 19,585
  • 30
  • 119
  • 191
0

There is no build in ForEach extension method. You can create your own, but I do not see any problem with the code you have.

Community
  • 1
  • 1
Magnus
  • 45,362
  • 8
  • 80
  • 118
  • I'm not sure that is 100% correct, if you convert the IEnumerable to a list, you can foreach off the list. Also i'm not sure why my lambda example doesn't work. – The Muffin Man Jul 09 '11 at 21:23
  • The `ForEach` you are using is not an extension method to IEnumerable, but belongs to `List`. – Magnus Jul 09 '11 at 21:27