【问题标题】:C# filling 2d Array from a single array in a loopC# 在循环中从单个数组填充 2d 数组
【发布时间】:2018-01-16 15:09:13
【问题描述】:

我正在循环读取带有坐标的文件(坐标示例 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] 收到错误消息 在[]中说错误的索引数量;

如何正确填充这个数组?

【问题讨论】:

  • 这段代码有点乱。为什么要将坐标转换为ints,然后什么都不做?您实际上在哪里实例化 orderedCoordinates 并且大小是多少?如果每行的坐标数似乎是恒定的并且等于8,为什么还要使用锯齿状数组?
  • 那我应该使用什么样的数组呢?

标签: c# arrays multidimensional-array


【解决方案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 查询不维护源数据的原始顺序。在这种情况下,这对您来说并不重要,因为您在选择后根据其他一些标准对坐标进行排序。但是,如果您决定跳过排序并在源文件中保留初始顺序,您可以在 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 =&gt; coord.Skip(1).Aggregate($"{coord[0]}", (b, c) =&gt; $"{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 =&gt; line.Length &gt; 0) 调用正在从最终结果中删除空坐标数组。

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

【讨论】:

  • 首先,感谢您的回答。我在返回时收到错误提示“输入字符串的格式不正确”
  • 哦,我试图读取一个带有坐标的文件,然后我想用整数中的坐标值创建一个数组
  • @user2928013 您好,我添加了第 3 次编辑,解决了您使用无效字符串格式的错误,并创建了您正在寻找的整数坐标数组的数组。另外,如果它解决了您的问题,请不要忘记将答案标记为有效! ?
猜你喜欢
  • 1970-01-01
  • 2019-10-16
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-21
  • 2011-10-08
  • 1970-01-01
相关资源
最近更新 更多