C#从循环中的单个数组填充2d数组

时间:2018-01-16 15:09:14

标签: c# arrays multidimensional-array

我正在读取循环中坐标的文件(坐标示例714050 437850 714050 437840 2 2 2 2),每一行都将变成一个整数数组。 然后我需要用坐标数组填充数组。

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; 

到目前为止,这是我的代码,但是我收到了一个错误 sortedCoordinates[lines][[i] = temp[i] 在[];

中说错误的索引数

如何正确填充此数组?

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题,例如:

  • 您从未初始化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查询不会维护源数据的原始排序。在这种情况下,当您在选择之后根据一些其他标准对坐标进行排序时,对您来说并不重要。但是,如果您决定跳过排序并保留源文件中的初始顺序,您可以在AsOrdered()之后立即添加AsParallel()调用来执行此操作,它将像传统的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)正在删除空的entires(在你的情况下是最后一个空行),而Where(line => line.Length > 0)调用正在从最终结果中删除空坐标数组。

或者,如果您不确定哪些行可能会有不正确的格式,您只需将int.Parse调用替换为int.TryParse,并在那里应用一些自定义逻辑。