Lambda expression as function parameter

I have the following code

List<int> GetIndices<T>(List<T> list, ?????? condition { var result = list .Select((p, index) => index) .Where(condition); return result.ToList(); } 

And I would name it as GetIndices(someList, (p, index) => (someList[index].Height < someList[index - 1].Height))

What is the correct condition type?

+6
source share
4 answers

There is an error in your code: Where expects a delegate that returns a bool value and has a list item type as input.

 var result = list .Select((p, index) => index) // projects the element to it index (of type int) .Where(condition); // => expects Func<int, bool> 

So you will need Func<int,bool>

However, from your specification, I think you want Func<T,int,bool> , which means that you need to rewrite your implementation of GetIndices as

 var result = list .Select((p, index) => new {p, index}) .Where(x => condition(xp, x.index)) .Select(x => x.index); 
+4
source
 Func<T, bool> 

Should do the trick, but you have to change your lambda a bit, because you cannot pass an index (if you want to use the condition in the Where clause). You can easily change your lambda to:

 p => someList[someList.IndexOf(p).Height < someList[someList.IndexOf(p)-1].Height 

For future reference, the MSDN documentation for extension methods is great as soon as you learn how to read it (this part takes a bit):

MSDN - Enumerable.Where Method

Since this is an extension method, the first parameter ( IEnumerable<TSource> ) is the collection that you call the method ( List<T> in your case).

The second parameter is what you need to combine. Since the documentation calls Func<TSource, bool> and TSource T in your case ... you get Func<T, bool>

+1
source

As with Jeroch, you need to fix the original index. The condition Funct<T,int,bool> that you pass in should be known only about the element and its index, and not the anonymous type created in the request, so the condition has changed a bit. It should also handle the situation where the index == 0 and, therefore, there are no previous elements (index - 1).

 class Program { static void Main( string[] args ) { var items = Item.GetItems(); // mind the case where index == 0 so you don't grab an item out of bounds var ind = GetIndices( items, ( p, index ) => ( h.index == 0 ) ? false : p.Height < items[ index - 1 ].Height ); } static List<int> GetIndices<T>( List<T> list, Func<T, int, bool> condition ) { var res = list .Select( ( item, index ) => new { item, index } ) // capture original index .Where( h => condition( h.item, h.index ) ) .Select( h => h.index ); // reduce to the index again return res.ToList(); } } class Item { public int Height { get; set; } public Item( int h ) { Height = h; } static public List<Item> GetItems() { return new List<Item>( new[]{ new Item(1), new Item(4), new Item(2), new Item(5) } ); } } 
+1
source

Try Func<bool> .

Or rather, an option with the correct number of input parameters.

0
source

Source: https://habr.com/ru/post/887844/


All Articles