Reputation: 88
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
Reputation: 4567
There are a few things wrong with your code, for example:
sortedCoordinates
variablelines
variable in a parallel loop without any thread-safety measuresortedCoordinates
variable name, so I assume you want to sort those coordinates, but you're never actually doing anything about thattempInt
array, but you're never actually using itYou 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 possibleSelect
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