简体   繁体   English

从txt文件创建2D数组

[英]Create 2D array from txt file

Okay so I've managed to read in a .txt file... now I'm trying to figure the best way to convert this information into a 2D array. 好的,所以我设法读了一个.txt文件......现在我想找到将这些信息转换成2D数组的最佳方法。

My text file (first two number provide height and width): 我的文本文件(前两个数字提供高度和宽度):

5
5
0,0,0,0,0
0,0,0,0,0
0,0,1,0,0
0,1,1,1,0
1,1,1,1,1

My C# / XNA: 我的C#/ XNA:

string fileContents = string.Empty;
try
{
    using (StreamReader reader = new StreamReader("Content/map.txt"))
    {
        fileContents = reader.ReadToEnd().ToString();
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

Now what I need to do next is define the size of the 2-dimensional map array and then populate the entry values... this is where I'm getting a bit stuck and have found various ways I can loop through the data but I don't think any of them have been terribly tidy. 现在我需要做的是定义二维地图数组的大小,然后填充条目值...这是我有点卡住的地方,并找到了各种方法,我可以循环数据,但我不要以为他们中的任何一个都非常整洁。

What I've tried to do is have one loops which splits by newline... and then another loop which splits by comma delimiter. 我试图做的是有一个循环按换行分割...然后另一个循环用逗号分隔符分割。

Is this the best way to do it... or are there better alternatives? 这是最好的方式......还是有更好的选择?

It can be done with LINQ but that is only practical when you want (accept) an array-of-array, int[][] instead of a straight 2-dimensional int[,] . 它可以用LINQ完成,但只有当你想要(接受)一个数组数组, int[][]而不是直接的二维int[,]时才能实现。

int[][] data = 
    File.ReadLines(fileName)
    .Skip(2)
    .Select(l => l.Split(',').Select(n => int.Parse(n)).ToArray())
    .ToArray();

The code below doesn't require the first to rows in your sample .CSV file: 下面的代码不需要示例.CSV文件中的第一行到第一行:

5
5

I'd prefer it this way, but as a consequence, the code below reads the file twice. 我更喜欢这种方式,但结果是下面的代码读取文件两次。 It would take a small modification use the first two rows in your sample instead. 只需要进行一些小修改就可以使用样本中的前两行。

private int[,] LoadData(string inputFilePath)
{
  int[,] data = null;

  if (File.Exists(inputFilePath))
  {
    Dictionary<string, int> counts = GetRowAndColumnCounts(inputFilePath);

    int rowCount = counts["row_count"];
    int columnCount = counts["column_count"];

    data = new int[rowCount, columnCount];

    using (StreamReader sr = File.OpenText(inputFilePath))
    {
      string s = "";
      string[] split = null;

      for (int i = 0; (s = sr.ReadLine()) != null; i++)
      {
        split = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

        for (int j = 0; j < columnCount; j++)
        {
          data[i, j] = int.Parse(split[j]);
        }
      }
    }
  }
  else
  {
    throw new FileDoesNotExistException("Input file does not exist");
  }

  return data;
}

private Dictionary<string, int> GetRowAndColumnCounts(string inputFilePath)
{
  int rowCount = 0;
  int columnCount = 0;

  if (File.Exists(inputFilePath))
  {
    using (StreamReader sr = File.OpenText(inputFilePath))
    {
      string[] split = null;
      int lineCount = 0;

      for (string s = sr.ReadLine(); s != null; s = sr.ReadLine())
      {
        split = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

        if (columnCount == 0)
        {
          columnCount = split.Length;
        }

        lineCount++;
      }

      rowCount = lineCount;
    }

    if (rowCount == 0 || columnCount == 0)
    {
      throw new FileEmptyException("No input data");
    }
  }
  else
  {
    throw new FileDoesNotExistException("Input file does not exist");
  }

  Dictionary<string, int> counts = new Dictionary<string, int>();

  counts.Add("row_count", rowCount);
  counts.Add("column_count", columnCount);

  return counts;
}

Here's the solution I've come up with which appears to work. 这是我提出的解决方案似乎有效。

int[,] txtmap;
int height = 0;
int width = 0;
string fileContents = string.Empty;

try
{
    using (StreamReader reader = new StreamReader("Content/map.txt"))
    {
        fileContents = reader.ReadToEnd().ToString();
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

string[] parts = fileContents.Split(new string[] { "\r\n" }, StringSplitOptions.None);
for (int i = 0; i < parts.Length; i++)
{
    if (i == 0)
    {
        // set width
        width = Int16.Parse(parts[i]);
    }
    else if (i == 1)
    {
        // set height
        height = Int16.Parse(parts[i]);

        txtmap = new int[width, height];
    }

    if (i > 1)
    {
        // loop through tiles and assign them as needed
        string[] tiles = parts[i].Split(new string[] { "," }, StringSplitOptions.None);
        for (int j = 0; j < tiles.Length; j++)
        {
            txtmap[i - 2, j] = Int16.Parse(tiles[j]);
        }
    }
}

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

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