473,413 Members | 1,989 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,413 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 3616
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
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.