0

I have a text file that contains product information on each line, in the form of "productCode,productName,amountInStock,etc.."

I've used File.ReadAllLines to store each line as an element in an array, and now I'm using those strings to assign values to a list of product structs.

Here is the code being used to split those strings from the array into substrings:

foreach (String line in readProducts)
{
    productData = line.Split(',');
    readProducts[foreachCount] = productData;
    foreachCount++;
}

Which gives me this error in Visual Studio:

Cannot implicitly convert type 'string[]' to 'string'

What would be the best way to accomplish this task, assuming that I must use structs rather than classes?

5
  • The readProducts[foreachCount] gives you string as readProducts would be array of strings whereas productData is array of strings. Array of strings could not be assigned to string. This is what the error message is telling. Commented Apr 13, 2016 at 4:58
  • Why must you use structs rather than classes? Commented Apr 13, 2016 at 5:03
  • The code is part of an assessment which specified structs. While I don't think I actually need to use structs, the lecturer is unavailable to ask and I'd rather not risk changing it. Commented Apr 13, 2016 at 5:18
  • You are getting ahead of yourself. Your first task is to define the struct. My advice is to carefully design your struct; make sure that it follows the guidelines for value types. It should be small, immutable and logically a value; if it is not all three of those things then a struct is likely the wrong choice. Once you have your struct, then work out how to construct one of them from one line. Once you've done that then you can figure out how to construct many from many lines. Walk before you run. Commented Apr 13, 2016 at 5:27
  • The code I shared isn't literally the first line of code in the program. I have the struct defined and with the value types that I've been required to have as part of the assessment, I can also easily take the data and use it to define one of them. That's why I asked this question. I have many structs, not just one, and I'd rather not define them all one at a time. Commented Apr 13, 2016 at 5:36

4 Answers 4

0

Use this way

List<string[]> readProducts = new List<string[]>();
foreach (String line in readProducts)
        {
            productData = line.Split(',');
            readProducts.Add(productData);
        }
Sign up to request clarification or add additional context in comments.

4 Comments

This is a really verbose form of readProducts.Select(x => x.Split(',')).ToList().
The issue with that is if readProducts is now a list of String arrays, it no longer contains the lines from the text file, so I can't read the lines from it.
0

Here is a better option for you:

Let product be the class, contains properties such as productCode, productName,amountInStock,etc.. as you mentioned in the question. you can create a list of product and directly assign the input values to the list as like the following:

string path="path here"
List<product> ProductList = new List<product>();
foreach (string line in File.ReadAllLines(path))
{
    string[] productDetails = line.Split(',');
    ProductList.Add(new product() { productCode = productDetails[0], productName = productDetails[1] }); 
}

Where the Product class looks like:

public class product
{
    public string  productCode { get; set; }
    public string  productName { get; set; }
    // rest of properties
}

Comments

0

You can use Select to project to a new collection:

var allItems = readProducts.Select(line => line.Split(','));  // collection of string arrays

or to project to a new type:

var allProducts = readProducts.Select(line => line.Split(','))  // collection of string arrays
                              .Select(array => new Product {
                                              productCode   = array[0],
                                              productName   = array[1],
                                              amountInStock = array[2], 
                                                  // etc.
                                              });  // collection of Products

5 Comments

I'm pretty sure I understand how your first example works, though I cannot for the life of me figure out why Select is called Select instead of something more accurate like DoToEach. Your second example however I don't get, could you please explain it to me?
@SpaceOstrich: It's called Select because it is commonly used to select a property from an item. customers.Select(c => c.Address) turns a sequence of customers into a sequence of addresses; it selects the address from each customer. This operation is commonly called map in other languages, which is an even more obscure analogy. (That the relationship between the thing being selected from and the thing being selected is analogous to the relationship between a figure on a map and the corresponding figure in real life.)
I've been plugging away at it and I'm close to having the answer, I've still not quite got the hang of Select. In D Stanley's examples he uses "line". What exactly is line in this context? A local variable? What is assigned to it?
@SpaceOstrich If you're not comfortable with Linq or lambda syntax then a plain foreach is probably better for you. Bottom line is to loop over the collection, create something from the item in the collection, and add that to a new collection. That's what Select does. Think of line as the foreach variable (equivalent to foreach(var line in readProducts))
@SpaceOstrich: Here is an implementation of Select: public static IEnumerable<R> Select<A, R>(this IEnumerable<A> items, Func<A, R> selector) { foreach (A item in items) yield return selector(item); }. The selector is a function. line => line.Split(',') is a function; that's the function passed as the selector to the Select method. Make sense?
0

Using System and jagged arrays, I was able to solve the problem. Here is the code used in the working program.

int i = 0;
String[][] allProducts = new String[readProducts.Length][];
var parsedProduct = readProducts.Select(item => item.Split(','));
foreach (var item in parsedProduct)
    {
        allProducts[i] = item;
        i++;
    }

allProducts[][] is a jagged array. Otherwise known as an Array of Arrays.

parsedProduct is similar to the jagged array, each element contains another array with the substrings extracted from the current line of readProduct as their elements.

allProducts's elements are assigned the contents of parsedProducts's elements by the foreach loop.

As far as I can tell, there isn't any way to cut out the middle man and just use Select() on readProducts directly. But I could be wrong.

1 Comment

Won't you consider LINQ solution?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.