FancyLord
FancyLord

Reputation: 88

C# filling 2d Array from a single array in a loop

Im reading a file with coordinates in a loop(example of a coordinate 714050 437850 714050 437840 2 2 2 2), every line will be turned into an array of integers. then I need to fill an array with arrays of coordinates.

public string[] coordinates;
    public int lines = 0;
    public string[][] sortedCoordinates;

    public void loadValues()
    {
        DateTime start = DateTime.Now;
        coordinates = File.ReadAllLines(path);
        Parallel.For(0, coordinates.Length, X =>    
        {

            string[] temp = coordinates[X].Split();
            int[] tempInt = Array.ConvertAll(temp, int.Parse);
            for (int i = 0; i <=7; i++)
            {
                sortedCoordinates[lines][[i] = temp[i];

            }
            lines += 1; 

this is my code so far, but I get an error at
sortedCoordinates[lines][[i] = temp[i] saying wrong number of indices inside[];

How can I fill this array properly?

Upvotes: 0

Views: 458

Answers (1)

Sergio0694
Sergio0694

Reputation: 4567

There are a few things wrong with your code, for example:

  • You never initialized the sortedCoordinates variable
  • You're accessing the lines variable in a parallel loop without any thread-safety measure
  • You're using a sortedCoordinates variable name, so I assume you want to sort those coordinates, but you're never actually doing anything about that
  • You're creating that tempInt array, but you're never actually using it

You could rewrite your code using PLINQ (Parallel-LINQ) this way:

String[] lines = coordinates = File.ReadAllLines(path);
String[][] coordinates = lines.AsParallel().Select(line =>
{
    String[] parts = line.Split(' ');
    return parts.OrderBy(int.Parse).ToArray();
}).ToArray();

Let's look at what's going on here:

  • lines.AsParallel() initializes a PLINQ query, so that it'll automatically be executed using more than a single core, if possible
  • The Select call projects every line, first by splitting it into the different substrings with the coordinates, using line.Split(' ') and then using parts.OrderBy(int.Parse).ToArray() to sort the values in each line in ascending order, as it seems you'd like to do in your example. If you're not sure about the OrderBy(int.Parse) part, that's a method group, so I'm just passing the int.Parse method without actually declaring a lambda there.

NOTE: as you can see here, by default a PLINQ query doesn't maintain the original ordering of the source data. In this context, it doesn't matter to you as you're ordering the coordinates according to some other criteria after the selection. But, should you decide to skip the sorting and to keep the initial order in your source file, you can just add an AsOrdered() call right after AsParallel() to do that and it will work just like a traditional LINQ query.

EDIT #2: not being entirely sure about what you're trying to do, since the code you posted is not 100% clear, here's a different option you could use, if you'd like to parse all the coordinates first and then sort them out using some criteria of your choosing:

String[] lines = coordinates = File.ReadAllLines(path);
int[][] coordinates = lines.AsParallel().Select(line =>
{
    String[] parts = line.Split(' ');
    return parts.Select(int.Parse).ToArray();
}).OrderBy(coord => coord.Skip(1).Aggregate($"{coord[0]}", (b, c) => $"{b}{c}")).ToArray();

Here, I'm selecting the coordinate parts for each line, and then coord => coord.Skip(1).Aggregate($"{coord[0]}", (b, c) => $"{b}{c}") is just sorting the final int[][] return value, in this example I'm concatenating the coordinates in each line alphabetically, but you could change this to sort the coordinates according to your own desired method. In this case, the sorting is performed on the string returned by the inner Aggregate query. This expression is just concatenating each coordinate read as a string (done with $"{coord[0]}", see string interpolation).

EDIT #3: the exception your were getting is probably because you had an empty line at the end of the lines read by the file, which caused the int.Parse method to crash. You can use this code to solve the issue, and get your array of arrays of integer coordinates:

int[][] coordinates = lines.AsParallel().Select(line =>
{
    String[] parts = line.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
    return parts.Select(int.Parse).ToArray();
}).Where(line => line.Length > 0).ToArray();

The only difference here is that Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries) is removing the empty entires (the last empty line in your case) and the Where(line => line.Length > 0) call is removing empty coordinates arrays from the end result.

Alternatively, if you're not sure where some line could have an improper formatting, you could just replace your int.Parse call with int.TryParse, and apply some custom logic there.

Upvotes: 1

Related Questions