String Array to Int Array

A

AMP

Hello
I get 2 errors in the following code that I cant Debug without some
help.
They are both in the TryParse function. Seems simple enough.The Errors
are Below.
private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
foreach (string Card in CardsToBeSortedArray)
{
UInt32.TryParse(Card, out IntCard);

}

}

Error 1 The best overloaded method match for 'uint.TryParse(string, out
uint)' has some invalid arguments
Error 2 Argument '2': cannot convert from 'out uint[]' to 'out uint'

I would appreciate some enlightening
Thanks
Mike
 
D

Dustin Campbell

Hello
I get 2 errors in the following code that I cant Debug without some
help.
They are both in the TryParse function. Seems simple enough.The Errors
are Below.
private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
foreach (string Card in CardsToBeSortedArray)
{
UInt32.TryParse(Card, out IntCard);
}

}

Error 1 The best overloaded method match for 'uint.TryParse(string,
out
uint)' has some invalid arguments
Error 2 Argument '2': cannot convert from 'out uint[]' to 'out uint'
I would appreciate some enlightening

You can't pass a uint[] where only a uint is expected. You have to do this:

private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
for (int i = 0; i < CardsToBeSortedArray.Length; i++)
UInt32.TryParse(CardsToBeSortedArray, out IntCard);
}

But, since you're using .NET Framework 2.0, you might try using the Array.ConvertAll<TInput,
TOutput> method instead:

private static void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray, delegate(string
card)
{
uint result;
UInt32.TryParse(card, out result);
return result;
});
}


Best Regards,
Dustin Campbell
Developer Express Inc.
 
T

Tom Porterfield

AMP said:
Hello
I get 2 errors in the following code that I cant Debug without some
help.
They are both in the TryParse function. Seems simple enough.The Errors
are Below.
private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
foreach (string Card in CardsToBeSortedArray)
{
UInt32.TryParse(Card, out IntCard);

}

}

Error 1 The best overloaded method match for 'uint.TryParse(string, out
uint)' has some invalid arguments
Error 2 Argument '2': cannot convert from 'out uint[]' to 'out uint'

As the second error states, TryParse needs a 'out uint' as its second
parameter, you are passing 'out uint[]'. You need to pass a specific index
of the array. I would rework the loop as follows:

private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
for (int i = 0; i < CardsToBeSortedArray.Length; i++)
{
uint.TryParse(CardsToBeSortedArray, out IntCard);
}
}
 
T

Tom Porterfield

Dustin said:
You can't pass a uint[] where only a uint is expected. You have to do
this:
private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
for (int i = 0; i < CardsToBeSortedArray.Length; i++)
UInt32.TryParse(CardsToBeSortedArray, out IntCard);
}

But, since you're using .NET Framework 2.0, you might try using the
Array.ConvertAll<TInput, TOutput> method instead:

private static void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray,
delegate(string card)
{
uint result;
UInt32.TryParse(card, out result);
return result;
});
}


Help me understand something. The second implementation is more code,
requires generics and delegates, and is harder to read, than the first. So
what are the advantages of doing it that way?
 
D

Dustin Campbell

Dustin said:
You can't pass a uint[] where only a uint is expected. You have to do
this:
private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
for (int i = 0; i < CardsToBeSortedArray.Length; i++)
UInt32.TryParse(CardsToBeSortedArray, out IntCard);
}
But, since you're using .NET Framework 2.0, you might try using the
Array.ConvertAll<TInput, TOutput> method instead:

private static void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray,
delegate(string card)
{
uint result;
UInt32.TryParse(card, out result);
return result;
});
}

Help me understand something. The second implementation is more code,
requires generics and delegates, and is harder to read, than the
first. So what are the advantages of doing it that way?


You gave several reasons against the second version. I'll address each:

1. The second implementation is more code.

Yes, the second version contains 14 more characters and two more lines. However,
it removes a loop that is arguably difficult to read. I used an anonymous
method to keep the code in one method so that comparisans could be made.
In reality, I might write it like this:

private uint CardToUInt32(string card)
{
uint result;
UInt32.TryParse(card, out result);
return result;
}
private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray, CardToUInt32);
}

That pushes the anonymous method into its own method and promotes reuse and
increases readability.

Note that there are very strong reasons to use anonymous methods in some
cases because they actually reduse code.

2. Requires generics and delegates.

I fail to see how using language features in C# 2.0 is a disadvantage as
it is clear that the code in the original post is using .NET Framework 2.0.
You can tell because UInt32.TryParse() is being used. That didn't exist before
2.0.

3. It's harder to read.

True. As best practice, code that uses an anonymous method for good reason
(e.g. to create a closure) should be moved to its own method. But, if you
look at the code that I posted for point #1, it is easy to create a situation
where the code is actually much better than falling back on a for-loop. It's
true that the for-loop is marginally faster but the difference is quite small.

Best Regards,
Dustin Campbell
Developer Express Inc.
 
C

Christof Nordiek

Newsbeitrag
private static void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray,
delegate(string card) {
uint result;
UInt32.TryParse(card, out result);
return result;
});
}

Could also be written as:

private static void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray,
delegate(string
card)
{ retun UInt32.TryParse(card, out result);});
}
 
C

Christof Nordiek

Tom Porterfield said:
Dustin said:
You can't pass a uint[] where only a uint is expected. You have to do
this:
private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
for (int i = 0; i < CardsToBeSortedArray.Length; i++)
UInt32.TryParse(CardsToBeSortedArray, out IntCard);
}

But, since you're using .NET Framework 2.0, you might try using the
Array.ConvertAll<TInput, TOutput> method instead:

private static void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray,
delegate(string card)
{
uint result;
UInt32.TryParse(card, out result);
return result;
});
}


Help me understand something. The second implementation is more code,
requires generics and delegates, and is harder to read, than the first.
So what are the advantages of doing it that way?


If you find it harder to read, simply don't use it. ;-)
 
M

Marc Gravell

No it couldn't; uint.TryParse returns a bool, where-as Converter<string,
uint> must accept a string and return a uint. It is not compatible.

Marc
 
M

Marc Gravell

I'm not so convinced in this case...

Look at the pros and cons of doing it this way...

pros: none; previous example showed it was very simple to do in another
(very clear) way
cons: harder to read *PLUS* all the other (very valid) comments [although
generics at least should be ubiquitious by now]

So if it doesn't gain you anything, but makes the code more complex and
hence probably both buggier (see TryParse anti-example) and harder to
debug... doesn't that just shout *do it the easy way!*

Granted there are definite cases for using delegates and methods such as
ConvertAll<>, but I'm not sure that this is one of them, and as such I would
counter "poorest excuse" with "most sensible design decision".

Marc
 
T

Tom Porterfield

Could also be written as:

private static void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray,
delegate(string
card)
{ retun UInt32.TryParse(card, out result);});
}

No, that doesn't compile, and even if fixed doesn't work the same way.
You've never declared result. Even if you did, you are returning the
return value of TryParse which is a bool that indicates success or failure
of the ability to parse the string into a uint. What he wants to place in
the array is the value of the uint after parsing, meaning he needs back the
undeclared result as Dustin has in his implementation.
 
C

Christof Nordiek

Marc and Tom are right, this simply isn't right. My fault.

Christof Nordiek said:
Newsbeitrag
private static void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray,
delegate(string card) {
uint result;
UInt32.TryParse(card, out result);
return result;
});
}

Could also be written as:

private static void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = Array.ConvertAll<string, uint>(CardsToBeSortedArray,
delegate(string
card)
{ retun UInt32.TryParse(card, out result);});
}
 
D

Dustin Campbell

If you find it harder to read, simply don't use it. ;-)
That's one of the poorest excuses I've heard to not use something.

Agreed. My goal was simply to show that the Array.ConvertAll<TInput, TOutput>
method exists and can be used for simple array conversion operations. The
truth is, I think that the original method is difficult to read and doesn't
really exhibit good design. This helped the anonymous method to overcomplicate
things even further because anonymous methods *should* be short. For reference,
here it is again:

private void ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
foreach (string Card in CardsToBeSortedArray)
{
UInt32.TryParse(Card, out IntCard);
}
}

And a working, sort-of-complete version:

private uint[] ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
for (int i = 0; i < CardsToBeSortedArray.Length; i++)
UInt32.TryParse(CardsToBeSortedArray, out IntCard);

return IntCard;
}

IMO, using UInt32.TryParse this way makes the method far more difficult to
read. It's almost as if UInt32.TryParse is being shoe-horned in. Because
of the way in which UInt32.TryParse is designed, a mental jump has to be
made because the assignment actually happens at the end of the method call.
Also, you must to have the intimate knowledge that UInt32.TryParse will set
IntCard to zero if it fails. So, the code in this method is semantically
coupled to UInt32.TryParse and that makes a very simple operation much harder
to read.

Here's one way to improve readability:

private uint ParseCard(string card)
{
uint result;
if (!UInt32.TryParse(card, out result))
result = 0;

return result;
}
private uint[] ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
uint[] IntCard = new uint[CardsToBeSortedArray.Length];
for (int i = 0; i < CardsToBeSortedArray.Length; i++)
IntCard = ParseCard(CardsToBeSortedArray);

return IntCard;
}

The call to UInt32.TryParse has been extracted to a more readable method
called "ParseCard". In addition, the semantic coupling to UInt32.TryParse
has been removed because the code no longer assumes that zero is returned
on failure. So, if Microsoft does anything insane or if the code runs on
a different .NET platform, we're protected against changes there.

And now, Array.ConvertAll can be used to reduce the code:

private uint[] ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
return Array.ConvertAll<string, uint>(CardsToBeSortedArray, delegate(string
card) { return ParseCard(card); });
}

Or, if you prefer not using an anonymous method, you can can simple specify
the method and reduce the code further:

private uint[] ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
return Array.ConvertAll<string, uint>(CardsToBeSortedArray, ParseCard);
}

I actually dislike that code a bit because it isn't clear what is going on.
It's harder to see that ParseCard is a method that is going to be called
with a specific parameter and its return value used. So, I prefer the clarity
of an anonymous method -- even though I detest the "delegate" keyword it
requires. That said, lambda expressions realy excite me because I can improve
the readability of the Array.ConvertAll call in some cool ways. In C# 3.0,
if a lambda expression is used, the compiler has enough information to figure
out what the generic arguments of Array.ConvertAll should be. So, the code
becomes this:

private uint[] ConvertLabelStringToArray(string p)
{
string[] CardsToBeSortedArray = p.Split(' ');
return Array.ConvertAll(CardsToBeSortedArray, card => ParseCard(card));
}

I like this most of all because it gives me the readable qualities that I
liked about the anonymous method example and makes it more succinct at the
same time. But, then again, I've been playing with lambda expressions a great
deal so I'm pretty comfortable with them.

Best Regards,
Dustin Campbell
Developer Express Inc.
 
L

Lucian Wischik

Tom Porterfield said:
Help me understand something. The second implementation is more code,
requires generics and delegates, and is harder to read, than the first. So
what are the advantages of doing it that way?

You must be new to IT, yes?

:)
 
D

Dustin Campbell

Help me understand something. The second implementation is more
You must be new to IT, yes?

Please don't make insulting comments.

Best Regards,
Dustin Campbell
Developer Express Inc.
 
L

Lucian Wischik

Lucian Wischik said:
You must be new to IT, yes?
:)

Clarification: as indicated by the smiley, it was a joke. The joke is
that in software engineering we like overly-complicated solutions with
too many layers of abstractions. It's the same joke as this one:

------------

How the way people code "Hello World" varies depending on their age
and job:

High School/Jr.High
10 PRINT "HELLO WORLD"
20 END


First year in College
program Hello(input, output)
begin
writeln('Hello World');
end.


Senior year in College
(defun hello
(print
(cons 'Hello (list 'World))))


New professional
#include <stdio.h>

void main(void)
{
char *message[] = {"Hello ", "World"};
int i;
for(i = 0; i < 2; ++i)
printf("%s", message);
printf("\n");
}


Seasoned professional
#include <iostream.h>
#include <string.h>
class string
{
private:
int size;
char *ptr;
public:
string() : size(0), ptr(new char('\0')) {}
string(const string &s) : size(s.size)
{
ptr = new char[size + 1];
strcpy(ptr, s.ptr);
}
~string()
{
delete [] ptr;
}
friend ostream &operator <<(ostream &, const string &);
string &operator=(const char *);
};

ostream &operator<<(ostream &stream, const string &s)
{
return(stream << s.ptr);
}
string &string::blush:perator=(const char *chrs)
{
if (this != &chrs)
{
delete [] ptr;
size = strlen(chrs);
ptr = new char[size + 1];
strcpy(ptr, chrs);
}
return(*this);
}
int main()
{
string str;
str = "Hello World";
cout << str << endl;
return(0);
}
 
O

Otis Mukinfus

[snip]

Good Lucian! I understood your original tongue in cheek joke.

I've mastered every one of the variations below. ;O)
------------

How the way people code "Hello World" varies depending on their age
and job:

High School/Jr.High
10 PRINT "HELLO WORLD"
20 END


First year in College
program Hello(input, output)
begin
writeln('Hello World');
end.


Senior year in College
(defun hello
(print
(cons 'Hello (list 'World))))


New professional
#include <stdio.h>

void main(void)
{
char *message[] = {"Hello ", "World"};
int i;
for(i = 0; i < 2; ++i)
printf("%s", message);
printf("\n");
}


Seasoned professional
#include <iostream.h>
#include <string.h>
class string
{
private:
int size;
char *ptr;
public:
string() : size(0), ptr(new char('\0')) {}
string(const string &s) : size(s.size)
{
ptr = new char[size + 1];
strcpy(ptr, s.ptr);
}
~string()
{
delete [] ptr;
}
friend ostream &operator <<(ostream &, const string &);
string &operator=(const char *);
};

ostream &operator<<(ostream &stream, const string &s)
{
return(stream << s.ptr);
}
string &string::blush:perator=(const char *chrs)
{
if (this != &chrs)
{
delete [] ptr;
size = strlen(chrs);
ptr = new char[size + 1];
strcpy(ptr, chrs);
}
return(*this);
}
int main()
{
string str;
str = "Hello World";
cout << str << endl;
return(0);
}

Good luck with your project,

Otis Mukinfus
http://www.arltex.com
http://www.tomchilders.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top