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.