您的代码有一些问题,例如:
- 您从未初始化过
sortedCoordinates 变量
- 您正在并行循环中访问
lines 变量,而没有任何线程安全措施
- 您使用的是
sortedCoordinates 变量名,因此我假设您想要对这些坐标进行排序,但您实际上从未对此做任何事情
- 您正在创建
tempInt 数组,但您从未真正使用它
您可以通过这种方式使用 PLINQ (Parallel-LINQ) 重写您的代码:
String[] lines = coordinates = File.ReadAllLines(path);
String[][] coordinates = lines.AsParallel().Select(line =>
{
String[] parts = line.Split(' ');
return parts.OrderBy(int.Parse).ToArray();
}).ToArray();
让我们看看这里发生了什么:
-
lines.AsParallel() 初始化 PLINQ 查询,以便在可能的情况下使用多个内核自动执行它
-
Select 调用会投影每一行,首先通过使用 line.Split(' ') 将其拆分为具有坐标的不同子字符串,然后使用 parts.OrderBy(int.Parse).ToArray() 以升序对每行中的值进行排序,就像你看起来的那样我想在你的例子中做。如果您不确定 OrderBy(int.Parse) 部分,那是 method group,所以我只是传递了 int.Parse 方法,而实际上没有在那里声明一个 lambda。
注意: 如您所见here,默认情况下,PLINQ 查询不维护源数据的原始顺序。在这种情况下,这对您来说并不重要,因为您在选择后根据其他一些标准对坐标进行排序。但是,如果您决定跳过排序并在源文件中保留初始顺序,您可以在 AsParallel() 之后添加一个 AsOrdered() 调用来执行此操作,它将像传统的 LINQ 查询一样工作。
编辑 #2: 不完全确定您要做什么,因为您发布的代码不是 100% 清楚,如果您愿意,可以使用其他选项喜欢先解析所有坐标,然后使用您选择的某些标准对其进行排序:
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();
在这里,我为每一行选择坐标部分,然后coord => coord.Skip(1).Aggregate($"{coord[0]}", (b, c) => $"{b}{c}") 只是对最终的int[][] 返回值进行排序,在这个例子中,我按字母顺序连接每行中的坐标,但你可以更改这可以根据您自己想要的方法对坐标进行排序。在这种情况下,对内部Aggregate 查询返回的字符串执行排序。这个表达式只是连接每个读取为字符串的坐标(使用$"{coord[0]}" 完成,参见string interpolation)。
编辑#3:您得到的异常可能是因为您在文件读取的行末尾有一个空行,这导致int.Parse 方法崩溃。您可以使用此代码来解决问题,并获取整数坐标数组的数组:
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();
这里唯一的区别是 Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries) 正在删除空的整体(在您的情况下是最后一个空行),而 Where(line => line.Length > 0) 调用正在从最终结果中删除空坐标数组。
或者,如果您不确定某些行的格式可能不正确,您可以将您的 int.Parse 调用替换为 int.TryParse,并在那里应用一些自定义逻辑。