Whidbey Readiness Quiz: Converting array values


Thinking about my last little quiz, I realize there are thousands (literally) of new methods across the framework in Whidbey.  How better to introduce\explain them than illustrating the problem they are intended to fix..

 

Let’s say you had this code:

        string[] inputValues = {“0”,“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9”,“10”,“bad value”};

        int[] outputValues;

        outputValues = (int[])inputValues;

Clearly that last line will not compile….

foo.cs(11,24): error CS0030: Cannot convert type ‘string[]’ to ‘int[]’

 

But how do you convert all the that string[] to an int[]?  What if you want out of range inputs to map to -1?  See if you can do it with no loops (foreach, while, for, etc), oh, and while you are at it no exception handling either…  And for extra credit, print the odd values out to the console in red ;-).

Comments (22)

  1. Nat says:

    private static int Converter(string from) {

    try {

    return Convert.ToInt32(from);

    }

    catch {

    Console.ForegroundColor = ConsoleColor.Red;

    Console.WriteLine(from + " is invalid number");

    Console.ResetColor();

    return -1;

    }

    }

    static void Main(string[] args) {

    string[] inputValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "bad value" };

    int[] outputValues;

    outputValues = Array.ConvertAll<string, int>(inputValues, Converter);

    }

  2. Nat says:

    For no exception handling….

    private static int Converter(string from) {

    int val;

    if (int.TryParse(from, out val)) {

    return val;

    }

    else {

    Console.ForegroundColor = ConsoleColor.Red;

    Console.WriteLine(from + " is invalid number");

    Console.ResetColor();

    return -1;

    }

    }

    static void Main(string[] args) {

    string[] inputValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "bad value" };

    int[] outputValues;

    outputValues = Array.ConvertAll<string, int>(inputValues, Converter);

    }

  3. Uwe Keim says:

    If Nat’s version works, would this also work without an extra method by using these new Python-style "inline" functions (are they called anonymous functions?).

    Or are these kind of functions only available for event handler?

  4. dotnetjunky says:

    string[] inputValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "bad value" };

    int[] outputValues;

    outputValues = Array.ConvertAll<string, int>(inputValues, delegate(string from)

    {

    int to;

    if (!Int32.TryParse(from, out to))

    {

    to = -1;

    }

    return to;

    });

    Array.ForEach<int>(outputValues, delegate(int i)

    {

    if (i % 2 == 0)

    {

    Console.ResetColor();

    }

    else

    {

    Console.ForegroundColor = ConsoleColor.Red;

    }

    System.Console.WriteLine(i);

    }

    );

    System.Console.ReadLine();

  5. wulong says:

    funny you call it Python-style inlining… call me a pedant (and/or correct me if i’m wrong), but I think it was Lisp that introduced the concept 🙂

  6. Joe Duffy says:

    Wulong–

    C#’s not first in this game with the anonymous delegates syntax, and Python does have similar "apply function" features available. But you’re right: LISP was certainly the first to introduce this concept.

    It’d go a little something like this:

    (mapcar #'(lambda (x)

    (IF (INTEGERP x) x -1)

    ‘(0 1 2 3 4 5 6 7 8 9 10 BADVALUE))

    <joe/>

  7. AT says:

    Here is my crap:

    // Microsoft did a good job – but hide it under name System. Reveal it !

    using System;

    // Make everybody wondering if int is string of nope and if this will compile

    // I will not tell you 😉

    using @int = System.String;

    using System.Security.Permissions;

    // Let’s play safe – do not execute without user permission

    // This may be somethat strict – but safe

    [assembly: UIPermission(SecurityAction.RequestMinimum, Unrestricted = true)]

    [assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]

    namespace Blogs.Msdn.Com

    {

    /// <summary>

    /// Do you know when C#-script will be invented to get rid on this lame class construct ??

    /// </summary>

    class Readiness_Quiz

    {

    /// <summary>

    /// Default value to be used in place of invalid integers

    /// </summary>

    private const int DEFAULT_VALUE = -1;

    /// <summary>

    /// Method pretending to implement requerements from Brad Abrams

    /// <see href="http://blogs.msdn.com/brada/archive/2004/10/26/248324.aspx"&gt;

    /// Whidbey Readiness Quiz: Converting array values

    /// </see>

    /// </summary>

    /// <param name="args">Ignored. Used only by real geeks who unable to use GUI</param>

    static void Main(string[] args)

    {

    // Expected total number of fingers on Homo-Sapiens hands

    string[] inputValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "bad value" };

    // The same for Marsians

    int[] outputValues;

    // Lame hack. Ask NASA for complete Homo-Sapiens -> Marsians migration

    outputValues = Array.ConvertAll<string, int>(inputValues, delegate(string from)

    {

    int ret;

    // Why known ? int can be different from Int32

    // Let’s play safe

    if (!int.TryParse(from, out ret))

    {

    ret = DEFAULT_VALUE;

    // Yo ! Something wrong !

    Console.Beep();

    }

    if (ret % 2 == 0)

    {

    // Not a thread-safe 🙁

    ConsoleColor saved = Console.ForegroundColor;

    Console.ForegroundColor = ConsoleColor.Red;

    Console.WriteLine(ret);

    Console.ForegroundColor = saved;

    }

    else

    {

    // But this is lame 😉

    Console.WriteLine(ret);

    }

    // Return Marsians their fingers

    return ret;

    }

    );

    }

    }

    }

  8. AT says:

    Even more lame answer – do it by-hand:

    string[] inputValues = {"0","1","2","3","4","5","6","7","8","9","10","bad value"};

    int[] outputValues = {0,1,2,3,4,5,6,7,8,9,10,-1};

    Console output you can draw in Microsoft Paint 😉

  9. Nat says:

    Misread the description on color information a bit 😛

    string[] inputValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "bad value" };

    int[] outputValues;

    outputValues = Array.ConvertAll<string, int>(inputValues, delegate(string from)

    {

    int i;

    if (!int.TryParse(from, out i)) i = -1;

    if ((i & 1) == 1)

    Console.ForegroundColor = ConsoleColor.Red;

    else

    Console.ResetColor();

    Console.WriteLine(i);

    return i;

    }

    );

    Console.ReadLine();

  10. AT says:

    Nat, dotnetjunky, Why do you assume that console color were initialy default ? As well – why you forget to restore color back to original if finished on odd number ?

    Not good 😉

    Everybody has bugs – even my submission 😉

  11. G says:

    AT… your code has completely befuddled me… please explain

    using @int = System.String;

    and why you need that? (With a comment that makes sense to a human please) In other words… WTF!!!

  12. G says:

    AT, also your foreground coloring does not work. The requirement was that the color should depend on the index into the array, not the converted array value.

  13. Nat says:

    True…. so this one might be a little better 🙂

    Misread the description on color information a bit 😛

    string[] inputValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "bad value" };

    int[] outputValues;

    outputValues = Array.ConvertAll<string, int>(inputValues, delegate(string from)

    {

    int i;

    if (!int.TryParse(from, out i)) i = -1;

    if ((i & 1) == 1)

    Console.ForegroundColor = ConsoleColor.Red;

    else

    Console.WriteLine(i);

    Console.ResetColor();

    return i;

    }

    );

    Console.ReadLine();

  14. AT says:

    G:

    @int " I will not tell you ;-)" Read C# specs. This is nice feature allowed even in versions before C# 2.0.

    "print the odd values" It’s clear that "odd values". Sure – I’ve printed even values – but this no way related to "odd indexes" 😉

    Nat:

    Your if (i & 1 == 1 ) does not provide any real performance benefits – but decrease readability. As well it’s flawed – why you are ignoring odd values by simply setting color ? Always use {} – this is mandatory for error-free coding.

    As well you are reseting both foreground and background color by ResetColor() if it was set to non-standart before running your method. Even Main(String[] args) can be called from others functions – it’s not always an entry point.

  15. Nat says:

    AT, can you have a constructive comment here? Do not be too much sarcastic. It is just a simple snippet.

    P.S.I know that the code is not perfect. Even the last one I posted still has some problem since I forgot to remove "else" before posting it.

  16. Dan Golick says:

    The @ allows a keyword to be used as an identifier.

    What the heck AT is doing with @ I don’t know. I think he’s just trying to mess with us.

  17. paulb says:

    The extra credit is for someone else:

    string[] inputValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "bad value" };

    int[] outputValues;

    outputValues = Array.ConvertAll<string, int>(inputValues, delegate(string from){

    int output;

    if (int.TryParse(from, out output )) {

    return output;

    } else {

    return -1;

    }

    });

  18. AT says:

    Dan: Exactly ! You got the point. My entire sniplet is real mess (if you are unable to figure this from my comments). Coding / C# are not boring as everything think 😉

  19. dotnetjunky says:

    AT, i think the main focus of the quiz is on the new Array.ConvertAll method and anonymous method construct, NOT on those trivial console’s color thing. That’s why i didn’t pay much attention to it when I wrote my snippets.

  20. AT says:

    dotnetjunky: You posted your source code to web-site. This mean that some people can start using it and hit unexpected problems you were able to solve using two-lines.

    This is not good to post buggy code to public.

    But overall – I agree this quiz about ConvertAll – so it’s pretty fine to create bugs in everything else – but "extra credit" must not apply for this 🙂

  21. dotnetjunky says:

    AT: Quote from you "This is not good to post buggy code to public".

    I really don’t understand your statement. Well, let me tell you this: even sample codes in MSDN articles contain bugs. And are you sure that your codes is perfectly correct ? The point here is that these public codes are for learning purposes only, not for production uses. If somebody uses my snippet codes (which is posted at a very informal place like this), then it’s their fault, not mine.

    Also, my code is just a "snippet" only, not a complete program. I posted it here to answer Brad’s quiz. Why would you keep insisting it’s buggy while it satisfies all Brad’s requirements ?