简体   繁体   English

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

[英]C# filling 2d Array from a single array in a loop

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. 我在循环中读取具有坐标的文件(坐标示例为714050 437850 714050 437840 2 2 2 2),每一行都将变成整数数组。 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[]; sortedCoordinates[lines][[i] = temp[i]说里面的索引数量错误[];

How can I fill this array properly? 如何正确填充此数组?

There are a few things wrong with your code, for example: 您的代码有些错误,例如:

  • You never initialized the sortedCoordinates variable 您从未初始化sortedCoordinates变量
  • You're accessing the lines variable in a parallel loop without any thread-safety measure 您正在并行循环中访问lines变量,而没有任何线程安全措施
  • 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 您使用的是sortedCoordinates变量名称,所以我假设您想对这些坐标进行排序,但是您实际上从未对此做任何事情
  • You're creating that tempInt array, but you're never actually using it 您正在创建该tempInt数组,但从未真正使用过它

You could rewrite your code using PLINQ (Parallel-LINQ) this way: 您可以通过以下方式使用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();

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 lines.AsParallel()初始化PLINQ查询,以便在可能的情况下使用多个内核自动执行该查询
  • 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. Select调用会line.Split(' ')每行,首先通过使用line.Split(' ')将其拆分为带有坐标的不同子字符串,然后使用parts.OrderBy(int.Parse).ToArray()对每一行中的值进行排序升序,好像您想在示例中那样。 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. 如果您不确定OrderBy(int.Parse)部分, OrderBy(int.Parse) 方法组 ,因此我只是传递了int.Parse方法,而没有实际在其中声明lambda。

NOTE: as you can see here , by default a PLINQ query doesn't maintain the original ordering of the source data. 注意:正如您在此处看到的那样,默认情况下,PLINQ查询不会保留源数据的原始顺序。 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. 但是,如果你决定跳过排序和保持原始的顺序在源文件中,你可以添加一个AsOrdered()调用后立即AsParallel()做到这一点,它的工作就像一个传统的LINQ查询。

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: 编辑#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();

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. 在这里,我为每条线选择坐标部分,然后选择coord => coord.Skip(1).Aggregate($"{coord[0]}", (b, c) => $"{b}{c}")只是对最终的int[][]返回值进行排序,在此示例中,我将按字母顺序连接每行中的坐标,但是您可以更改此值以根据自己想要的方法对坐标进行排序。 In this case, the sorting is performed on the string returned by the inner Aggregate query. 在这种情况下,将对内部Aggregate查询返回的字符串进行排序。 This expression is just concatenating each coordinate read as a string (done with $"{coord[0]}" , see string interpolation ). 该表达式只是将每个坐标读取为一个字符串(用$"{coord[0]}" ,请参阅字符串插值 )。

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. 编辑#3:您得到的异常可能是因为在文件读取的行的末尾有一个空行,这导致int.Parse方法崩溃。 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. 唯一的区别是Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)删除了空整数(您情况下的最后一个空行),而Where(line => line.Length > 0)调用被删除了最终结果中的空坐标数组。

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. 另外,如果您不确定某些行的格式可能不正确,则可以将int.Parse调用替换为int.TryParse ,然后在其中应用一些自定义逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM