473,326 Members | 2,133 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Re: Should you simplify this code? Write only code

On Sep 9, 9:41*am, raylopez99 <raylope...@yahoo.comwrote:
Scott Meyers in his 2001 book on STL / C++ claims that the following
code is optimal--what is the C# way and should you follow his example
and try and do this in LINQ? *Pseudo code is OK, I'm just looking for
a conceptual answer.
It's tricky in .NET for two reasons:

1) LINQ doesn't have any concept of "remove"
2) List<T>.RemoveAll doesn't pass in the index (which makes sense as
it would then need to

If List<Tsupported some sort of "view" which also exposed RemoveAll,
it would be easy:

int lastIndex = list.FindLastIndex(value =value >= y);
list.SubList(lastIndex).RemoveAll(value =value < x);

But as "SubList" doesn't exist, I suspect in this case I'd have to go
back to a foreach loop.
In many other cases it *does* make sense to chain functions together -
there are just limitations in this particular question.
I personally don't like the C++, but that's as much to do with the
library design and lack of lambda expressions as anything else.
Note that if instead of removing data from the current list you were
happy with a new list with the retained elements, it's really easy:

int lastIndex = list.FindLastIndex(value =value >= y);
List<XnewList = list.Where((index, value) =index < lastIndex ||
value >= x).ToList();

Still two statements (to avoid finding the last index repeatedly) but
it's still sound. (I haven't tested the above, admittedly.)

Jon
Sep 9 '08 #1
5 3607
raylopez99 <ra********@yahoo.comwrote:
On Sep 9, 3:30*am, "Jon Skeet [C# MVP]" <sk...@pobox.comwrote:

Note that if instead of removing data from the current list you were
happy with a new list with the retained elements, it's really easy:

int lastIndex = list.FindLastIndex(value =value >= y);
List<XnewList = list.Where((index, value) =index < lastIndex ||
value >= x).ToList();
I tried this and it failed to compile because there is no .Where
operator for lists.
Something tells me you forgot "using System.Linq;"

List<Timplements IEnumerable<T>, so Where certainly *does* work.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Sep 11 '08 #2
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
*/

}

Sep 11 '08 #3
raylopez99 <ra********@yahoo.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.
Yes, you need to know the syntax. That's the same with everything
though. If someone didn't know about the "using" directive, would you
suggest they just fully qualified every name with the namespace? I
doubt it - I think you'd suggest they should learn about the "using"
directive. Ditto lambda expressions. Yes, they're "new and different" -
but they're well worth learning, and really not very difficult.
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?)"
You don't cast to avoid the compiler error - you either call ToList()
to create an actual list, or just work with the IEnumerable<int>. The
value returned from Where *isn't* a List.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Sep 11 '08 #4
On Sep 11, 6:53*am, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
>
You don't cast to avoid the compiler error - you either call ToList()
to create an actual list, or just work with the IEnumerable<int>. The
value returned from Where *isn't* a List.
Yes, that's right. I tried this and it works now:

//change this: IEnumerable<intquery2 = newList4.Where(new
PredicateClass2(x, lastIndexJon).MyPredicate);

//to this:

List<intnewList234 = new List<int>();

newList234 = newList4.Where(new PredicateClass2(x,
lastIndexJon).MyPredicate).ToList(); //<--note .ToList() added, now a
list

And newList234 is now a list.

Curious how long it took you to learn LINQ syntax--seems no references
exist out there, and the examples given in books (including your own)
are simplistic (seems).

RL
Sep 11 '08 #5
On Sep 11, 10:18*pm, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
Basically:

Deferred = will execute later, when you ask for data
Immediate = executes now

Buffered = needs to read to the end of the input data before yielding
any results (e.g. Reverse)
Streaming = can yield data as it reads it, e.g. Select or Where.
I see these terms bandied about but nobody ever directly explains (or
it's rather oblique) as to when to use buffered, when to use
streaming, etc. Conceptually, buffered takes more memory, and
probably takes longer to run, since you have to construct a temporary
container to store the data, the replicate the data, then read out,
while streaming is faster and takes memory, since you only are
traversing your original data "on the fly". But with streaming you
cannot "back up" or randomly access data, you have to take whatever
the stream position is giving you.

It would be helpful to know when to buffer, when to stream. Most
books tend to caution against using too many loops (buffer) or copying
to many structures (ditto), so read-once sequential 'streaming' seems
to be the default preferred choice. That said, this following code,
setting up a .ToArray() (Buffer) has saved me from a compiler error--

foreach (MyClass X in MyClassList.ToArray()) //this avoids
the runtime error: " Collection was modified; enumeration operation
may not execute." -creates a temporary .ToArray() in loop for
enumeration purposes only, which is the standard solution to this
problem
{
// do stuff that changes MyClassList (a list containing MyClass
parameters/values) here
}

RL
Sep 14 '08 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: beliavsky | last post by:
To print a list with a specified format one can write (for example) for j in : print "%6d"%j, print The code print "%6d"%
29
by: Flzw | last post by:
Alright, here is a simple function I coded, won't be hard understanding what it does, and YES, I know, you will probably tell me it's awful code, I would like to know how to write it better, maybe...
0
by: Stylus Studio | last post by:
DataDirect XQuery(TM) is the First Embeddable Component for XQuery That is Modeled after the XQuery API for Java(TM) (XQJ) BEDFORD, Mass.--Sept. 20, 2005--DataDirect Technologies...
8
by: ben | last post by:
i have a bit of code, that works absolutely fine as is, but seems over complicated/long winded. is there anyway to shorten/simplify it? the code is below. description of it: it's like strcpy in...
4
by: pms | last post by:
Need suggestions to improve this program. using System; namespace CalculateWage { class GetEmployeeDetails {
6
by: Patrick | last post by:
Hi All, Kind of new to this. What I have below works, but I am wondering if there is a way to make it more efficient/simpler instead of having to write an if, tr, td, blah for each datatype. How...
3
by: tshad | last post by:
I have dataGrid that I am filling from a List Collection and need to sort it by the various columns. So I need to be able to sort the Collection and found that you have to set up your own...
1
AmLegacy
by: AmLegacy | last post by:
I'm having a hard time figuring out how to simplify the fractions. Can anyone look at this code and see if you can see something I don't. //This is the fraction adding function void add_fractions...
1
by: raylopez99 | last post by:
Scott Meyers in his 2001 book on STL / C++ claims that the following code is optimal--what is the C# way and should you follow his example and try and do this in LINQ? Pseudo code is OK, I'm just...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.