Trouble Using System.Array.ForEach

  • Thread starter Thread starter Nathan Sokalski
  • Start date Start date
N

Nathan Sokalski

I am trying to use the System.Array.ForEach method in VB.NET. The action
that I want to perform on each of the Array values is:

Private Function AddQuotes(ByVal value As String) As String
Return String.Format("'{0}'", value)
End Function

Basically, I just want to surround each value with single quotes. However, I
am having trouble getting this to work using the System.Array.ForEach
method. This may be partially because I am not very experienced with Actions
or Delegates, so if somebody could tell me what I am doing wrong, I would
appreciate it. Thanks. (NOTE: The Array that I want to modify the values of
is not one that I have permission to modify (it is
System.Globalization.DateTimeFormatInfo.CurrentInfo.DayNames()), so if
anybody knows of a way to do this inline without declaring another Array,
that would be nice as well)
 
The Action type for the ForEach method requires a subroutine that takes no
parameters. I've never tried this method, but it doesn't seem useful for
your situation. How about starting with the following:


For Each dayofweek As String In _
System.Globalization.DateTimeFormatInfo.CurrentInfo.DayNames

Console.Out.WriteLine(AddQuotes(dayofweek))
Next
 
That would get me the quotes around each of the days, but I was hoping to do
something like this:

String.Join(",",System.Globalization.DateTimeFormatInfo.CurrentInfo.DayNames())

so that I could have the DayNames separated by commas. However, the code
that I have above would not place each day inside quotes. Do I know of ways
to create this comma-delimited String? Of course, but using a for loop would
require me to either include an if statement determining when I am at the
last value or manually remove the comma from the end of the String. I
figured if I could just use the String.Join instead, I wouldn't have to deal
with so many Strings and If statements. And, even though it may be just a
thirst for knowledge, I would like to know how to use the ForEach method for
future reference. Thanks.
 
"'" & String.Join("','", DateTimeFormatInfo.CurrentInfo.DayNames) & "'"

or

String.Format("'{0}'", String.Join("','",
DateTimeFormatInfo.CurrentInfo.DayNames))
 
This will avoid the leading comma:


dim n as integer = CurrentInfo.DayNames.Length - 1
dim s as string = CurrentInfo.DayNames(0)

for i = 1 to n
s = string.Format("{0}, {1}", s, CurrentInfo.DayNames(i))
next
 
I know how to do string manipulation, that is a very simple task. However,
in several of my cases I want to not only add quotes to each element, but
take the substring of it as well (for example, in some cases I want an array
of only the first letter of each day). The techniques people have mentioned
so far are great when I want the entire name, but when I need to do
something like get just the first letter, or if I want it in all capitals,
etc., I would require either a loop of some sort (which is what I am trying
to avoid) or the ForEach method. I appreciate everyone's suggestions on how
to use loops and string manipulation, but unfortunately (well, fortunately
actually) I already know those techniques. So unless you are going to help
me figure out how to use ForEach, save yourself the effort of showing me
string manipulation and help someone else that is still learning loops and
all the string manipulation techniques. But I still thank you for your time
and effort.
 
What is so evil about using a loop?


Nathan Sokalski said:
I know how to do string manipulation, that is a very simple task. However,
in several of my cases I want to not only add quotes to each element, but
take the substring of it as well (for example, in some cases I want an
array of only the first letter of each day). The techniques people have
mentioned so far are great when I want the entire name, but when I need to
do something like get just the first letter, or if I want it in all
capitals, etc., I would require either a loop of some sort (which is what I
am trying to avoid) or the ForEach method. I appreciate everyone's
suggestions on how to use loops and string manipulation, but unfortunately
(well, fortunately actually) I already know those techniques. So unless you
are going to help me figure out how to use ForEach, save yourself the
effort of showing me string manipulation and help someone else that is
still learning loops and all the string manipulation techniques. But I
still thank you for your time and effort.
 
It appeared from your last question, that you thought using a loop to build
the comma separated list would require an if-then clause to remove the comma
before the first iteration. The code I provided eliminates this.

You have shown several cases where you seem to want a solution "of a
particular form", rather than a solution. Perhaps someone can post an
example where Array.ForEach solved a problem for them, but to be honest with
you, I have never run into a case where it helped. I think if someone has an
example, it won't exactly fit your conditions.
 
You are definitely correct that you proved me wrong about the loop thing, at
least for the scenario of simply adding quotes, thank you very much for
providing that solution. However, I still have the scenarios where I need to
use only the first letter, or the first two letters, or capitalize, etc.,
and your solution does not work for these (unless I'm missing something
again), which I think are the scenarios I was thinking about when I
mentioned the If Then statement. And you may be right about the ForEach not
fitting my conditions, I really can't say for sure since I have never had
the opportunity to use ForEach, but either way, it never hurts to have extra
knowledge so that if a situation were to come up where it was fit I would
know it. Thanks.
 
I have nothing against loops, in fact in many cases, I try to use them to if
it can reduce the size of my code, but in this case, I could end up removing
both a loop and an if-then, as well as some string manipulation. So in this
case, I think the ForEach would shrink my code more than a loop. I feel
loops are very important and useful, but in this case I think I could do
better, as well as the fact that I want to learn certain things, and not
everything is included in the books I have (and I have a reasonable number,
and have read them cover to cover). I appreciate any and all help you can
give.
 
The reason that the Array.ForEach Generic method is not suitable for your
purposes in this case is that on each iteration of the 'hidden' loop, each
element of the array is paseed to the Action delegate Sub, ByVal. Note that
the Action delegate is a Sub and not a Function. This is complicated in that
the elements you are dealing with are strings, which, although being a
reference type, are immutable. Therefore the string that is passed to the
delegate is returned unaltered and the parent array is not modified.

Even if you use a For Each loop on the array of strings, the same behaviour
is exhibited because each iteration of the loop is operating on a copy of
the array element and not the array element itself, e.g.:

Dim _ss As String() = DateTimeFormatInfo.CurrentInfo.DayNames

For Each _s As String in _ss
_s = "'" & _s & "'"
Next

does not work because _s is only a copy of an element of _ss, whereas:

Dim _ss As String() = DateTimeFormatInfo.CurrentInfo.DayNames

For _i as Integer = 0 to _ss.Length - 1
_ss(_i) = "'" & _ss(_i) & "'"
Next

works because the content of each element is being manipulated directly via
the index.

While the Framework includes many methods on various classes that provides,
with a single call, the functionality that we might once have had to write
some code to achieve, there will not necessarily be a suitable Framework
method for everything you want to do.

NEVER be scared to get your hands dirty and write a bit of code and NEVER
expect that someone is going to provide a particular 'method' ready for you
to use 'out of the box'.

As a further word of advice, programming is not a competition to use the
least amout of code possible. It is rare that the smallest amount of code is
the most efficient.
 
Back
Top