On Sep 10, 10:34*pm, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
>
Something tells me you forgot "using System.Linq;"
List<Timplements IEnumerable<T>, so Where certainly *does* work.
Yes, I did forget System.Linq. Below is the demo program, it works.
I use two different ways: one, doing the "Linq" way you suggest, the
other, doing it through "delegate" type logic** (sorry if I have the
lingo wrong).
I think 'your' way* using anonymous types and lambda is 'easier', more
compact and works fine but only if you know the syntax. I could not
find anything on Online Help (F1 in Visual Studio 2008), except
through IntelliSense, how to get the syntax right, other than using
your suggestion in the previous thread, but during actual programming
I don't have your expertise around, unfortunately.
BTW, as a minor aside, if you can figure out a quick way of casting to
avoid this compiler error (see below), please let me know: "Cannot
implicitly convert type 'System.Collections.Generic.IEnumerable<int>'
to 'System.Collections.Generic.List<int>'. An explicit conversion
exists (are you missing a cast?)"
RL
* your way is this line below: "newList2 = newList2.Where((index,
value) =index < lastIndexJon && value >= x).ToList(); "
** the 'delegate logic' way is after this line below: //final way to
do it: use PredicateClass2
PS--ignore the first part of the program below, just pick up where the
program says "Console.WriteLine("start second example(s) here...")",
since the stuff before is from a slightly different thread. Also, the
x,y's are sometimes interchanged in the symbol variables, but the
point is simply this: the problem solution is to traverse a List of
integers, from 0 to 9 or so, then, using two 'pivots', namely five and
8, find all the elements in the List that are greater or equal to five
and less than eight. The answer is 5, 6 and 7, as shown.
/////////
// OUTPUT (output is as expected)
predicates - 9/11/2008
0 1 2 3 4 5 6 7 8 -10
lastIndex is: 8, firstIndex is 5
lastIndex2 is: 8
firstIndex2 is: 5
lastIndex3 is: 8
firstIndex3 is: 5
start second example(s) here...
lastIndexJon is 8
filtered newList2
i: 5 , i: 6 , i: 7 ,
queried newList3
query i: 5 query i: 6 query i: 7 query2's i: 5 query2's i: 6 query2's
i: 7
End of Program
Press any key to continue . . .
////////////
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//////////////////////////////////////////////////
// predicates - 9/11/2008
Console.WriteLine("\n predicates - 9/11/2008 ");
List<intnewList = new List<int>();
for (int i = 0; i < 10; i++)
{
newList.Add(i);
}
newList.Remove(9); //note: commenting out this line
gives: 0 1 2 3 4 5 6 7 8 -10 9 (ten elements) since nothing removed!
newList.Insert(9, -10); //gives output 0 1 2 3 4 5 6 7 8
-10
foreach (int i in newList)
{
Console.Write(" {0}", i);
}
Console.WriteLine("\n");
int y = 5;
int lastIndex = newList.FindLastIndex(value =value >=
y);
int firstIndex = newList.FindIndex(value =value >= y);
Console.WriteLine("lastIndex is: {0}, firstIndex is {1}",
lastIndex, firstIndex); //last index is 8 (i.e. List[8] = 8) first
index is 3 (List[3]= 3)
int lastIndex2 = newList.FindLastIndex(MyPredicate);
Console.WriteLine("lastIndex2 is: {0}", lastIndex2);
int firstIndex2 = newList.Find(MyPredicate);
Console.WriteLine("firstIndex2 is: {0}", firstIndex2);
int lastIndex3 = newList.FindLastIndex(new
PredicateClass(y).MyPredicate);
Console.WriteLine("lastIndex3 is: {0}", lastIndex3);
int firstIndex3 = newList.Find(new
PredicateClass(y).MyPredicate);
Console.WriteLine("firstIndex3 is: {0}", firstIndex3);
//////////////////////////////////////
Console.WriteLine("start second example(s) here...");
int lastIndexJon = newList.FindLastIndex(value =value >= y); //gives
value of '8'
Console.WriteLine("lastIndexJon is {0}", lastIndexJon);
List<intnewList2 = new List<int>();
for (int i = 0; i < 10; i++)
{
newList2.Add(i); //produces a list from (0 to 9)
}
List<intnewList3 = new List<int>(); //don't initialize, as this
catches what's filtered by the .where clause
List<intnewList4 = new List<int>();
int x = 5; //second pivot point
newList3 = newList2;
newList4 = newList2;
newList2 = newList2.Where((index, value) =index < lastIndexJon
&& value >= x).ToList();
// note .Where "overwrites" the newList2, no need to
create another new List
Console.Write("\n filtered newList2 \n");
foreach (int i in newList2)
{
Console.Write(" i: {0} ,", i);
}
IEnumerable<intquery = newList3.Where((index, value) =index <
lastIndexJon && value >= x).ToList();
//strangely, the LHS, 'query', is also equivalent to a list, so you
can put on the LHS a list, such as: List<intanotherList = new
List<int>(); anotherList = newList3.Where((index, value) =index <
lastIndexJon && value >= x).ToList();
Console.Write("\n queried newList3 \n");
foreach(int i in query)
{
Console.Write("query i: {0} ",i);
}
//final way to do it: use PredicateClass2
IEnumerable<intquery2 = newList4.Where(new PredicateClass2(x,
lastIndexJon).MyPredicate);
//unfortunately, you cannot convert the LHS 'query2' into a list
directly, as you can with variable 'query' above, as you get compiler
error: "Cannot implicitly convert type
'System.Collections.Generic.IEnumerable<int>' to
'System.Collections.Generic.List<int>'. An explicit conversion exists
(are you missing a cast?)"
foreach (int i in query2)
{
Console.Write("query2's i: {0} ", i);
}
Console.Write("\n End of Program \n");
}
//////////////// end of Main() /////////////////
private static bool MyPredicate(int value)
{
if (value >= 5)
{ return true; }
else
{ return false; }
}
public class PredicateClass
{
private int _y;
public PredicateClass(int y)
{
_y = y;
}
public bool MyPredicate(int value)
{
if (value >= _y)
{ return true; }
else
{ return false; }
}
}
public class PredicateClass2
{
private int _y;
private int _x;
public PredicateClass2(int y, int x)
{
_y = y;
_x = x;
}
public bool MyPredicate(int value)
{
if (value >= _y && value < _x)
{ return true; }
else
{ return false; }
}
}
}
/*
*
List<stringfruits = new List<string{ "apple", "passionfruit",
"banana", "mango", "orange", "blueberry", "grape", "strawberry" };
IEnumerable<stringquery = fruits.Where(fruit =fruit.Length < 6);
foreach (string fruit in query)
Console.WriteLine(fruit);
This code produces the following output:
apple
mango
grape
*/
}