Kyle Nally
Kyle Nally

Reputation: 35

split one array into two parallel arrays OR read directly into two arrays in C#

In my C# course I have been given the following data file for my current assignment (console program):

Combine,  1500.00
Oxen,    195.00
Mule,  200.00
Tractor,  4000.00
Truck,  12150.00
Trailer,  475.00

The spaces are part of the file, of course. I cannot save to or alter the data file in any way.

I need to read it in as a two-dimensional array (OR two parallel arrays) and then run a search against the array from user input. The program is supposed to be able to accept the following user input:

Equipment name, Beginning value, Years of Depreciation, and (if not already in the array) salvage value. If the equipment doesn't appear in the array, I'm to treat it as a new piece of equipment and, if that equipment is entered again, NOT have to input the salvage value.

Once I have all user input I'm to output the year and depreciated value per year. The program also needs a menu for user input, output, and exit.

We only Wednesday went through examples of searching within arrays; both the final exam and this assignment are due Monday. I've been searching this site and reading from three different texts for about eight hours straight trying to understand what I'm doing and I just do NOT get it at all (only eight people in the class have higher than a 70%, so I'm doing better than most, but STILL).

Here's the code I have written so far. For today I'm ONLY trying to get a proper two-dimensional array in place. My question is, have I correctly implemented a two-dimensional array, and if so, how do I reference each piece of equipment and salvage value from the file shown above, independently of each other?

public static void GetArrayFromFile()
{
    StreamReader equipmentFile = new StreamReader("SalvageData.TXT");
    string[,] salvageFileArray = new string[1, 6];
    for (int indexCounterA = 0; indexCounterA < 6; indexCounterA++)
    {
        if (equipmentFile.Peek() != -1)
        {
            for (int indexCounterB = 0; indexCounterB < 6; indexCounterB++)
            {
                if (equipmentFile.Peek() != -1)
                {
                    salvageFileArray[indexCounterA, indexCounterB] = equipmentFile.ReadLine();
                }
                else
                {
                    break;
                }
            }
        }
        else
        {
            break;
        }
    }
}

I'm very much over my head on this last assignment. I have NO IDEA how to proceed. Please, if anyone can help me with this... chime in.

Oh yes: no list objects, no char objects, no regex. This is a base-level introductory course; we haven't covered any of those and may not use them.

I really, really need some help here. I'm also going to need to search the array and compare user input, as I've said, so if anyone knows of any good "read from a CSV file into an array and then do some math with it" resources, I'd appreciate being pointed to that as well.

Thanks in advance, and my apologies if I'm repeating several asked-and-answered questions at once.

Upvotes: 2

Views: 981

Answers (2)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112342

You should not use an array if you have to look up values. A Dictionary<TKey, TValue> has been made especially for this task. It already contains an algorithm for fast lookup.

I would read the file like this:

private static Dictionary<string, decimal> ReadSalvageValuesFromFile(string fileName)
{
    string[] lines = File.ReadAllLines(fileName);
    var dict = new Dictionary<string, decimal>()
    foreach (string line in lines) {
        string[] parts = line.Split(',');
        decimal value;
        if (parts.Lengh >= 2 && Decimal.TryParse(parts[1].Trim(), out value)) {
            dict.Add(parts[0].Trim(), value);
        }
    }
    return dict;
}

Later, you can check if a value is in the dictionary like this

Dictionary<string, decimal> salvageValues = ReadSalvageValuesFromFile(@"C:\myFile.txt");
...
decimal salvage;
if (salvageValues.TryGetValue("Mule", out salvage)) {
    // use this value
} else {
    // let user enter new value
}

You can also update the dictionary with new values like this

salvageValues["Tractor"] = salvage;

If the entry was there, the value will be updated, otherwise a new entry will be created.


If you must use arrays, you can still use some of the ideas of the above code.

A 2-d array has the disadvantage that all the elements have the same type. If you have to store text as well as numbers this is not ideal, unless you want to store the numbers as text as well. Or you could create an object[] array that allows you to store any kind of data, at the price that you have to cast the items when retrieving them.

2 arrays in parallel have the advantage that they can have different types (e.g. string[] and decimal[]).

In any case you should create methods (subroutines) for the different operations. This makes the code easier to read and simplifies the task of creating the main application.

Using the method of Ron Beyer you can now easily read the file into a 2-d array.

Now you need a way to look up values in the array. A method doing it could look like this:

private static string LookupSalvage(string[,] salvages, string key)
{
    // Search within array (you seem to know how to do it)
    if (found) {
        return value;
    }

    return null;
}

Upvotes: 2

Ron Beyer
Ron Beyer

Reputation: 11273

Its an interesting topic, usually homework is frowned upon, but I'll help point you in the right direction since you aren't asking outright for the code.

First, you want to get an array from a file, so you need to create a function that will do that and return to you an array. This makes your function prototype become

public string[,] GetArrayFromFile(string fileName)

Notice how we are returning a 2-dimensional array. So now you want to read in the file, but you want to split that into the number of entries. You want to try to do this without hard-coding the number of elements in the array, because that would require prior knowledge of the input file (not sure if you are allowed to do that or not).

So, lets start out by reading the entire file in one step:

public string[,] GetArrayFromFile(string fileName)
{
    string[] fileData = File.ReadAllLines(fileName);
}

Now we know the first dimension of the array, which is the number of lines, the second dimension is 2, since there are 2 elements per line. So we can create the result array:

public string[,] GetArrayFromFile(string fileName)
{
    string[] fileData = File.ReadAllLines(fileName);

    string[,] result = new string[fileData.Length, 2];
}

The only thing that is left is to split the fileData into separate parts for each element, so to do that we'll have to use a for-loop (could be done with foreach, but I suspect that may be an "advanced" topic).

public string[,] GetArrayFromFile(string fileName)
{
    string[] fileData = File.ReadAllLines(fileName);

    string[,] result = new string[fileData.Length, 2];

    for (int i = 0; i < fileData.Length;i++)
    {
        string[] parts = fileData[i].Split(',');
        result[i, 0] = parts[0];
        result[i, 1] = parts[1];  //Probably want to .Trim() here
    }

    return result;
}

Which now becomes your entire function to get the array from the file, without using hard-coded "magic" numbers.

To use it, from the calling function call the GetArrayFromFile passing in the file name of your input file and store the result in a variable. The array then contains the first dimension as the line index, and the second dimension is the data. To search, loop through the first index and examine the second index for the equipment type. Once you find it, you can then look at the salvage value (probably want to convert it to an integer for comparison purposes).

Upvotes: 5

Related Questions